npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

next-captcha

v0.0.2

Published

Behavioral captcha generators for Node.js, including click, slide, drag, and rotate variants

Readme

English | 中文

Ecosystem

| Project | Desc | |----------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | document | Captcha Documentation | | online demo | Captcha Online Demo | | next-captcha | Node.js CAPTCHA Library | | go-captcha | Golang CAPTCHA Library | | py-captcha | Python CAPTCHA Library | | go-captcha-example | Golang + Web + APP Example | | go-captcha-assets | Embedded Resource Assets for Golang | | go-captcha-jslib | JavaScript CAPTCHA Library | | go-captcha-vue | Vue CAPTCHA Library | | go-captcha-react | React CAPTCHA Library | | go-captcha-angular | Angular CAPTCHA Library | | go-captcha-svelte | Svelte CAPTCHA Library | | go-captcha-solid | Solid CAPTCHA Library | | go-captcha-uni | UniApp CAPTCHA, compatible with Apps, Mini-Programs, and Fast Apps | | go-captcha-flutter | Flutter CAPTCHA Library | | go-captcha-service | GoCaptcha Service, supports binary and Docker image deployment, provides HTTP/gRPC interfaces, supports standalone and distributed modes (service discovery, load balancing, dynamic configuration) | | go-captcha-service-sdk | GoCaptcha Service SDK Toolkit, includes HTTP/gRPC request interfaces, supports static mode, service discovery, and load balancing. | | ... | |

Core Features

  • Diverse CAPTCHA Types: Supports Click, Slide, Rotate, and Drag-Drop behavioral CAPTCHAs for different interaction scenarios.
  • Highly Customizable: Flexible configuration of images, fonts, colors, angles, sizes, and behavior through options and resources.
  • Advanced Image Processing: Supports dynamic generation of master images, thumbnails, puzzle tiles, masks, and shadow effects.
  • Modular Architecture: Clear module boundaries for click, slide, slide-region, rotate, and shared base utilities.
  • TypeScript-Friendly Design: Ships with TypeScript declarations and works with CommonJS, native ESM, and TypeScript imports.
  • Cross-Platform Integration: Generated CAPTCHA images can be used in web applications, Node.js services, APIs, or hybrid app backends.

CAPTCHA Types

next-captcha supports the following four CAPTCHA types, each with its own interaction style, generation logic, and usage scenario:

  1. Click CAPTCHA: Users click specified text or shape targets on the master image, supporting text mode and shape mode.
  2. Slide CAPTCHA: Users slide a puzzle tile to the correct position on the master image, supporting basic mode and drag-drop mode.
  3. Drag-Drop CAPTCHA: A variant of the Slide CAPTCHA, allowing freer tile movement over a larger interaction area.
  4. Rotate CAPTCHA: Users rotate a thumbnail to visually align it with the master image angle.

Installation

npm install next-captcha

Runtime Requirements

  • Node.js 14+
  • A platform supported by @napi-rs/canvas

Importing Modules

CommonJS

const { ClickBuilder } = require('next-captcha');
const Click = require('next-captcha/click');

Native ESM

import { ClickBuilder } from 'next-captcha';
import * as Click from 'next-captcha/click';

TypeScript

import { ClickBuilder, loadImageFromPath } from 'next-captcha';
import { withChars, withBackgrounds } from 'next-captcha/click';

Package Exports

  • next-captcha
  • next-captcha/click
  • next-captcha/slide
  • next-captcha/slide-region
  • next-captcha/rotate
  • next-captcha/base/tools ← recommended for public image/font helpers
  • next-captcha/base/canvas-adapter ← advanced adapter customization only

Module Format Support

After build, the package publishes:

  • CommonJS for require()
  • Native ESM for import
  • TypeScript declarations for both styles

Base Utility Helpers

For normal consumers, prefer loadImageFromPath, loadImageFromBuffer, and registerFontFromPath from the main package entry, or use next-captcha/base/tools if you prefer subpath imports.

To keep from importing @napi-rs/canvas directly, the package exposes public helper utilities under next-captcha/base/tools:

  • loadImageFromPath(path)
  • loadImageFromBuffer(buffer)
  • registerFontFromPath(path, fontFace)

These helpers are built on top of the internal canvas adapter and are the recommended public API for loading images and registering fonts.


Click CAPTCHA

Click CAPTCHA asks the user to click specific targets on the master image.

Modes:

  • Text Mode: clickable characters
  • Shape Mode: clickable icons or shapes

How It Works

  1. Generate the master image (masterImage) with random items.
  2. Generate the thumbnail image (thumbImage) showing verification targets.
  3. The frontend captures click coordinates.
  4. The backend validates coordinates against the generated dots data.

Example: Text Click CAPTCHA

import { ClickBuilder, loadImageFromPath } from 'next-captcha';
import {
  withBackgrounds,
  withChars,
  withRangeLen,
  withRangeVerifyLen,
} from 'next-captcha/click';
import { loadImageFromPath } from 'next-captcha/base/tools';

const builder = new ClickBuilder();

builder.setOptions(
  withRangeLen({ min: 4, max: 6 }),
  withRangeVerifyLen({ min: 2, max: 4 })
);

builder.setResources(
  withChars(['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']),
  withBackgrounds([await loadImageFromPath('bg.png')])
);

const captcha = builder.make();
const data = await captcha.generate();

const dots = data.getData();
const masterImage = await data.getMasterImage().toBuffer();
const thumbImage = await data.getThumbImage().toBuffer();

Example: Shape Click CAPTCHA

import { ClickBuilder, loadImageFromPath } from 'next-captcha';
import { withBackgrounds, withShapes } from 'next-captcha/click';
import { loadImageFromPath } from 'next-captcha/base/tools';

const builder = new ClickBuilder();

builder.setResources(
  withBackgrounds([await loadImageFromPath('bg.png')]),
  withShapes(
    new Map([
      ['star', await loadImageFromPath('star.png')],
      ['heart', await loadImageFromPath('heart.png')],
      ['moon', await loadImageFromPath('moon.png')],
      ['cloud', await loadImageFromPath('cloud.png')],
      ['leaf', await loadImageFromPath('leaf.png')],
      ['sun', await loadImageFromPath('sun.png')],
    ])
  )
);

const captcha = builder.makeShape();
const data = await captcha.generate();

Create Instance

  • builder.make() → text click CAPTCHA
  • builder.makeShape() → shape click CAPTCHA

Click Options

| Option | Description | |---|---| | withFontDPI(number) | Set font DPI scale | | withImageSize({ width, height }) | Set master image size | | withRangeLen({ min, max }) | Set random item count range | | withRangeAnglePos([{ min, max }, ...]) | Set item rotation ranges | | withRangeSize({ min, max }) | Set rendered item size range | | withRangeColors(string[]) | Set master foreground colors | | withDisplayShadow(boolean) | Enable or disable text shadow | | withShadowColor(string) | Set shadow color | | withShadowPoint({ x, y }) | Set shadow offset | | withImageAlpha(number) | Set master background alpha | | withRangeThumbImageSize({ width, height }) | Set thumbnail size | | withRangeVerifyLen({ min, max }) | Set verification target count | | withDisabledRangeVerifyLen(boolean) | Verify all generated items | | withRangeThumbSize({ min, max }) | Set thumbnail item size range | | withRangeThumbColors(string[]) | Set thumbnail foreground colors | | withRangeThumbBgColors(string[]) | Set generated thumbnail background colors | | withRangeThumbBgDistort(number) | Set thumbnail distortion level | | withRangeThumbBgCirclesNum(number) | Set background circle count | | withRangeThumbBgSlimLineNum(number) | Set background line count | | withIsThumbNonDeformAbility(boolean) | Prevent thumbnail shapes from deforming | | withThumbDisturbAlpha(number) | Set thumbnail noise alpha | | withUseShapeOriginalColor(boolean) | Keep original shape colors |

Click Resources

| Resource | Description | |---|---| | withChars(string[]) | Set text seeds | | withShapes(Map<string, Image>) | Set shape seeds | | withFonts(any[]) | Set font resources | | withBackgrounds(any[]) | Set master backgrounds | | withThumbBackgrounds(any[]) | Set thumbnail backgrounds |

Click Captcha Data

| Method | Description | |---|---| | getData() | Returns Map<number, Dot> | | getMasterImage() | Returns master image data | | getThumbImage() | Returns thumbnail image data |

Click Validation

import { validate as validateClick } from 'next-captcha/click';
const ok = validateClick(srcX, srcY, x, y, width, height, padding);

Slide CAPTCHA / Drag-Drop CAPTCHA

Slide CAPTCHA asks the user to move a tile into the correct position.

Modes:

  • Basic Mode: horizontal slide with fixed Y-axis behavior
  • Drag-Drop Mode: freer drag positioning

Example

import { SlideBuilder, loadImageFromPath } from 'next-captcha';
import { withBackgrounds, withGraphImages } from 'next-captcha/slide';
import { loadImageFromPath } from 'next-captcha/base/tools';

const builder = new SlideBuilder();

builder.setResources(
  withBackgrounds([await loadImageFromPath('bg.png')]),
  withGraphImages([
    {
      overlayImage: await loadImageFromPath('tile.png'),
      shadowImage: await loadImageFromPath('tile-shadow.png'),
      maskImage: await loadImageFromPath('tile-mask.png'),
    },
  ])
);

const captcha = builder.make();
const data = await captcha.generate();

Drag-Drop Example

import { SlideRegionBuilder } from 'next-captcha/slide-region';

const builder = new SlideRegionBuilder();
const captcha = builder.makeDragDrop();

Create Instance

  • builder.make() → basic slide CAPTCHA
  • builder.makeDragDrop() → drag-drop CAPTCHA

Slide Options

| Option | Description | |---|---| | withImageSize({ width, height }) | Set master image size | | withImageAlpha(number) | Set tile and shadow alpha | | withRangeGraphSize({ min, max }) | Set block size range | | withRangeGraphAnglePos([{ min, max }, ...]) | Set block angle ranges | | withGenGraphNumber(number) | Set number of generated blocks | | withEnableGraphVerticalRandom(boolean) | Enable random vertical placement | | withRangeDeadZoneDirections(DeadZoneDirectionType[]) | Control dead-zone direction selection |

Slide Resources

| Resource | Description | |---|---| | withBackgrounds(any[]) | Set master backgrounds | | withGraphImages(GraphImage[]) | Set tile, shadow, and mask resources |

Slide Captcha Data

| Method | Description | |---|---| | getData() | Returns Block | | getMasterImage() | Returns master image data | | getTileImage() | Returns tile image data |

Slide Validation

import { validate as validateSlide } from 'next-captcha/slide';
const ok = validateSlide(srcX, srcY, x, y, padding);

Drag-Drop Alias Module

next-captcha/slide-region also provides:

  • SlideRegionBuilder
  • SlideRegionCaptcha
  • newSlideRegionBuilder()

Rotate CAPTCHA

Rotate CAPTCHA asks the user to rotate a thumbnail image until it visually matches the master image.

Example

import { RotateBuilder, loadImageFromPath } from 'next-captcha';
import { withImages, withRangeAnglePos } from 'next-captcha/rotate';
import { loadImageFromPath } from 'next-captcha/base/tools';

const builder = new RotateBuilder();

builder.setOptions(
  withRangeAnglePos([{ min: 30, max: 330 }])
);

builder.setResources(
  withImages([
    await loadImageFromPath('rotate-bg-1.png'),
    await loadImageFromPath('rotate-bg-2.png'),
  ])
);

const captcha = builder.make();
const data = await captcha.generate();

Rotate Options

| Option | Description | |---|---| | withImageSquareSize(number) | Set square master image size | | withRangeAnglePos([{ min, max }, ...]) | Set random rotation ranges | | withRangeThumbImageSquareSize(number[]) | Set candidate thumbnail sizes | | withThumbImageAlpha(number) | Set thumbnail alpha |

Rotate Resources

| Resource | Description | |---|---| | withImages(any[]) | Set rotate images |

Rotate Captcha Data

| Method | Description | |---|---| | getData() | Returns rotate Block | | getMasterImage() | Returns master image data | | getThumbImage() | Returns thumbnail image data |

Rotate Validation

import { validate as validateRotate } from 'next-captcha/rotate';
const ok = validateRotate(userAngle, targetAngle, padding);

Validation Helpers from Main Entry

import { validateClick, validateSlide, validateRotate } from 'next-captcha';

License

Apache-2.0