JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 1
  • Score
    100M100P100Q20378F
  • License MIT

A fully customizable CAPTCHA component built for modern web apps

Package Exports

  • @opentech-lab/custom-captcha
  • @opentech-lab/custom-captcha/types

Readme

Custom CAPTCHA – Build Your Own reCAPTCHA-Style Puzzle

A fully customizable CAPTCHA component built for modern React applications, with first-class Next.js support. Easily integrate it into your forms to stop bots, test user knowledge, or filter unwanted traffic using custom question sets and image-based puzzles.

When activated, the component displays as a centered modal dialog where users answer verification questions. Upon successful verification, it closes automatically and saves the verification status to localStorage. In Next.js applications, verification can also be handled server-side with SSR.

No backend server required – this is a frontend-focused CAPTCHA solution optimized for React and Next.js applications.

Features

  • Protect your website, pages and forms from spam and automation
  • Add your own custom questions (text, image, logic, drag-n-drop)
  • Puzzle types: multiple choice, single choice, text input, image selection
  • Language & culture aware: design puzzles specific to your audience
  • Simple integration with React (other frameworks coming soon)
  • Lightweight & dependency-free (core)

Quick Start Guide

This guide will walk you through setting up the Custom CAPTCHA in a React application.

1. Installation

First, add the package to your project:

npm install @opentech-lab/custom-captcha

2. Usage

Setup questions

import { CaptchaQuestion } from '@opentech-lab/custom-captcha/types';

export const captchaQuestion: CaptchaQuestion[] = [
  {
    id: '1',
    type: 'multiple-choice',
    question: 'What is number?',
    options: ['1', 'abc', '8', 'hello'],
    correctAnswer: ['1', '8'],
  },
  {
    id: '2',
    type: 'single-choice',
    question: 'What is 10 - 4?',
    options: ['5', '6', '7', '8'],
    correctAnswer: ['6'],
  },
  {
    id: '3',
    type: 'text-input',
    question: 'What is the capital of France?',
    correctAnswer: ['Paris'],
  },
  {
    id: '4',
    type: 'images-select',
    question: 'Select all cat images',
    images: [
      { src: '/images/cat1.jpg', answer: true },
      { src: '/images/cat2.jpg', answer: false },
      { src: '/images/cat3.jpg', answer: true },
    ],
    correctAnswer: [], // Not used for images-select, answers are in images array
  },
];

Configuration Options

import { CaptchaConfig } from '@opentech-lab/custom-captcha/types';

export const exampleConfig: CaptchaConfig = {
  questions: captchaQuestion,
  title: "Please complete this verification",
  expiryMinutes: 60,
  storageKey: "custom-captcha-verification",
  questionsToSolve: 2, // Only show 2 random questions from the pool
};

Configuration Properties

Property Type Default Description
questions CaptchaQuestion[] [] Array of questions for the CAPTCHA
title string "Verification Required" Title shown in the CAPTCHA dialog
expiryMinutes number 60 How long verification lasts (minutes)
storageKey string "custom-captcha-verification" Local storage key for verification status
questionsToSolve number 1 Number of questions to solve correctly
zIndex number 99999 Z-index for the CAPTCHA overlay
imageObjectFit string "contain" How images are fitted in image-select questions

Usage Examples

Basic Usage (Single Question)

// Shows 1 random question (default behavior)
<CustomCaptcha question={captchaQuestion} />

Limited Questions (Random Selection)

// Shows only 2 random questions from the pool
const config = {
  questions: captchaQuestion,
  questionsToSolve: 2,
  title: "Quick Verification"
};

<CustomCaptcha config={config} />

Full Configuration Example

// Complete setup with all options
const advancedConfig = {
  questions: captchaQuestion,
  title: "Security Check",
  expiryMinutes: 30,
  storageKey: "my-app-captcha",
  questionsToSolve: 3, // User must solve 3 questions correctly
  zIndex: 999999
};

<CustomCaptcha config={advancedConfig} />

Add in layout

import { CustomCaptcha } from '@opentech-lab/custom-captcha';
import { captchaQuestion, exampleConfig } from '@/config/captchaconfig';
// Types can be imported separately if needed
// import { CaptchaQuestion, CaptchaConfig } from '@opentech-lab/custom-captcha/types';

export default async function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <div>
      {children}
      <CustomCaptcha config={exampleConfig} />
      {/* Alternative: <CustomCaptcha question={captchaQuestion} /> */}
    </div>
  );
}

Key Features

Smart Question System

  • questionsToSolve: Specify how many questions users must solve correctly
  • Users can retry incorrect answers unlimited times (no attempt limits)
  • System presents new random questions until the required number is solved
  • If you have 10 questions but set questionsToSolve: 3, users need to solve any 3 correctly
  • Questions are selected randomly from the pool, avoiding recently solved ones when possible
  • Real-time progress tracking: Shows "Progress: 2 / 3 solved" at top and bottom
  • Button text changes: "Next" → "Complete" on final question

Ethics & Safety

This tool is designed for developers building secure and intentional communities. Use ideological or political filters responsibly. Avoid using CAPTCHAs in ways that could be discriminatory or violate local laws.

License

MIT

Contributing

PRs welcome. If you'd like to contribute new puzzle types, translations, or integrations (Vue, Svelte, etc.), feel free to open an issue or fork the repo.