MCPcopy Index your code
hub / github.com/altcha-org/altcha

github.com/altcha-org/altcha @v3.1.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release v3.1.0 ↗ · + Follow
126 symbols 317 edges 134 files 1 documented · 1% 3 cross-repo links
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

ALTCHA

ALTCHA is a self-hosted, privacy-first security solution that protects your websites, APIs, and online services from spam and abuse through an innovative proof-of-work mechanism. Unlike traditional CAPTCHAs that depend on intrusive methods like cookies or fingerprinting, ALTCHA delivers robust protection while respecting user privacy.

ALTCHA is fully compliant with:

For more details, visit altcha.org.

Playground

Want to see it in action? Visit the official ALTCHA Playground to experiment with widget configurations, fine-tune the Proof-of-Work (PoW) settings, and see how the security mechanisms hold up in real-time.

Open ALTCHA Playground

Features

  • Frictionless Experience: Eliminates frustrating visual puzzles by using background Proof-of-Work (PoW) for a seamless user journey.
  • Hardware-Resistant Security: Leverages Argon2 and Scrypt memory-bound algorithms to neutralize hardware acceleration (ASICs/GPUs) and sophisticated bot farms.
  • Accessible Code Challenges: Provides "Enter code from image" fallbacks with built-in audio support for visually impaired users.
  • Privacy by Design: Fully GDPR compliant and cookie-free—no tracking, no fingerprinting, and no data collection.
  • Universal Accessibility: Engineered to exceed WCAG 2.2 AA standards, ensuring compliance with the European Accessibility Act (EAA).
  • Lightweight: Minimal footprint, optimized for rapid page loads and high-performance environments.
  • 100% Self-Hosted: Maintain full sovereignty over your infrastructure with no reliance on third-party API availability.

What’s New in v3

  • Next-Gen PoW: Significant performance gains and reduced CPU overhead through an optimized verification mechanism.
  • Advanced Bot Defense: Native support for Argon2 and Scrypt, raising the cost of attack for automated scripts and specialized hardware.
  • Modern UI: Refined styling options, including a suite of new built-in themes and improved CSS custom property support.
  • Developer Experience: Improved TypeScript support and streamlined integration.

Migrating from v2

See MIGRATION-v2.md.

Examples

Explore starter templates for popular frameworks:

Server Integrations

Plugins & CMS

Usage

The ALTCHA widget is distributed as a Web Component.

1. Install ALTCHA

npm install altcha

Import in your main file:

import 'altcha';

Or load via <script> tag:

<script async defer src="https://github.com/altcha-org/altcha/raw/v3.1.0/altcha.js" type="module"></script>

2. Add <altcha-widget> to Your Forms

<form>
    <altcha-widget challenge="https://..."></altcha-widget>
</form>

See configuration options or the website integration docs.

3. Integrate with Your Server

Refer to the server documentation for implementation details.

Supported Browsers

ALTCHA works on modern browsers with Web Crypto API support (specifically crypto.subtle - caniuse.com).

Supported:

  • Chrome 67+ (desktop & Android)
  • Edge 79+
  • Firefox 63+ (desktop & Android)
  • Safari 11+ (macOS & iOS)
  • Any browser supporting Web Components + Web Crypto

Not Supported:

  • Internet Explorer 11 (or older)

Bundle Size

ALTCHA is optimized for performance:

Distribution Size (GZIPped)
ALTCHA 34 kB
ALTCHA with all translations 52 kB
Cloudflare Turnstile 85+ kB
hCaptcha 250+ kB
reCAPTCHA 300+ kB

When GZIPped, it totals about 34 kB, making ALTCHA’s widget about ~90% smaller than reCAPTCHA.

Content Security Policy (CSP)

The default bundle includes styles and workers in a single file. For strict CSP compliance, use scripts from /dist/external. Learn more in the documentation.

Configuration

Programmatic Configuration

The widget provides a global $altcha object to manage defaults, register new algorithms, or add custom translations.

To update an existing widget instance, use the .configure() method. This is the preferred way to handle complex objects or functions that cannot be passed via HTML attributes.

// Set defaults for all future widget instances:
$altcha.defaults.set({
    challenge: 'https://api.example.com/challenge',
    debug: true
});

// Update a specific instance dynamically:
const widget = document.querySelector('altcha-widget');
widget.configure({
    workers: 2,
    language: 'fr'
});

Attribute Configuration

For simple implementations, the widget supports a subset of configuration options directly as HTML attributes. For more advanced properties, use the programmatic approach above.

Supported Attributes:

<altcha-widget
    auto="off"
    challenge="https://api.example.com/challenge"
    configuration='{"minDuration": 1000}'
    display="standard"
    language="en"
    name="altcha"
    theme="default"
    type="checkbox"
    workers="4"
></altcha-widget>

[!TIP] The configuration attribute accepts a JSON-encoded string, allowing you to pass complex settings directly in your HTML markup.

Core Settings

  • name: The name attribute of the hidden input field containing the payload. (Default: "altcha")
  • challenge: The challenge data or the URL to fetch a new challenge from.
  • type: Visual style of the interaction element ('native', 'checkbox', or 'switch').
  • language: The ISO alpha-2 language code for localization (requires corresponding i18n file).
  • workers: The number of Web Workers to spawn for proof-of-work calculations.

Automation & Timing

  • auto: Determines when verification triggers automatically ('off', 'onfocus', 'onload', or 'onsubmit').
  • minDuration: The minimum verification time in milliseconds; adds an artificial delay if the PoW is faster. (Default: 500)
  • retryOnOutOfMemoryError: Automatically attempts to restart verification with fewer workers if the browser runs out of memory (Argon2 and Scrypt only).

UI & Display

  • display: The visual layout mode ('standard', 'bar', 'floating', 'overlay', or 'invisible').
  • barPlacement: Vertical position of the widget when display is set to bar ('bottom' or 'top').
  • hideLogo: Hides the ALTCHA logo icon.
  • hideFooter: Hides the "ALTCHA" attribution link.
  • validationMessage: Custom validation message for the HTML5 setCustomValidity API.

Floating Widget Settings

  • floatingAnchor: The element or CSS selector the floating UI attaches to. Defaults to the first submit button.
  • floatingPlacement: Preferred position relative to the anchor ('auto', 'bottom', or 'top').
  • floatingOffset: Vertical offset in pixels between the UI and its anchor. (Default: 12)
  • floatingPersist: Whether the floating widget remains visible after successful verification.
  • popoverPlacement: Preferred position of popovers relative to the widget ('auto', 'bottom', or 'top').

Modal & Challenge Settings

  • codeChallengeDisplay: UI layout for the code-challenge modal ('standard', 'overlay', or 'bottomsheet').
  • overlayContent: CSS selector for an element to be mirrored inside the overlay modal.
  • audioChallengeLanguage: Forces a specific language for audio-based challenges.
  • disableAutoFocus: Prevents the code-challenge modal from stealing focus when opened.

Advanced & Debugging

  • debug: Enables verbose logging in the browser console.
  • test: Mocks a successful verification for testing environments.
  • mockError: Forces the widget into a failed state for UI testing.
  • fetch: A custom fetch implementation for network requests.
  • humanInteractionSignature: Whether the collector for HIS is enabled (Default: true).
  • setCookie: When configured, sends the payload as a cookie.
  • timeout: Verification timeout in milliseconds (Default: 90_000).
  • verifyFunction: A custom verification handler that overrides default network verification.

Algorithms

ALTCHA supports multiple proof-of-work algorithms. PBKDF2/* and SHA-* are bundled with the main widget by default. Argon2 and Scrypt are memory-bound algorithms that resist hardware acceleration (ASICs/GPUs) but require importing their workers separately.

Supported algorithms:

  • PBKDF2/SHA-256 (default, bundled)
  • PBKDF2/SHA-384 (bundled)
  • PBKDF2/SHA-512 (bundled)
  • SHA-256 (bundled)
  • SHA-384 (bundled)
  • SHA-512 (bundled)
  • ARGON2ID (requires separate worker import)
  • SCRYPT (requires separate worker import)

If you use Argon2 or Scrypt, import their workers and register them via the $altcha.algorithms global before the widget initializes.

Adding Argon2 / Scrypt Workers (Vite)

Works with both altcha and altcha/external:

import 'altcha'; // or 'altcha/external'
import Argon2idWorker from 'altcha/workers/argon2id?worker';
import ScryptWorker from 'altcha/workers/scrypt?worker';

$altcha.algorithms.set('ARGON2ID', () => new Argon2idWorker());
$altcha.algorithms.set('SCRYPT', () => new ScryptWorker());

Without Bundler Worker Import Support

If your environment does not support ?worker imports, load the prebuilt worker files directly:

import 'altcha';

$altcha.algorithms.set(
    'ARGON2ID',
    () => new Worker('/path/to/node_modules/altcha/dist/workers/argon2id.js')
);
$altcha.algorithms.set(
    'SCRYPT',
    () => new Worker('/path/to/node_modules/altcha/dist/workers/scrypt.js')
);

Using altcha/external

altcha/external excludes all bundled workers, requiring you to register every algorithm explicitly. Use this for full control over which workers are loaded:

import 'altcha/external';
import Argon2idWorker from 'altcha/workers/argon2id?worker';
import Pbkdf2Worker from 'altcha/workers/pbkdf2?worker';
import ScryptWorker from 'altcha/workers/scrypt?worker';
import ShaWorker from 'altcha/workers/sha?worker';

$altcha.algorithms.set('PBKDF2/SHA-256', () => new Pbkdf2Worker());
$altcha.algorithms.set('PBKDF2/SHA-384', () => new Pbkdf2Worker());
$altcha.algorithms.set('PBKDF2/SHA-512', () => new Pbkdf2Worker());
$altcha.algorithms.set('SHA-256', () => new ShaWorker());
$altcha.algorithms.set('SHA-384', () => new ShaWorker());
$altcha.algorithms.set('SHA-512', () => new ShaWorker());
$altcha.algorithms.set('ARGON2ID', () => new Argon2idWorker());
$altcha.algorithms.set('SCRYPT', () => new ScryptWorker());

Cookies

By default, the widget sends the ALTCHA payload as a form field by creating a hidden input. It can also be configured to send the payload via a cookie.

To enable this behavior, use the setCookie configuration option:

widget.configure({
    setCookie: {
        name: 'altcha',
        path: '/'
    }
});

setCookie accepts the following cookie options:

interface SetCookieOptions {
    domain?: string;
    name?: string;
    maxAge?: number;
    path?: string;
    sameSite?: string;
    secure?: boolean;
}

Server Configuration

When the widget fetches a challenge from the server, the server can override widget configuration using either the X-Altcha-Config response header or the configuration property in the challenge response.

Example using the configuration property in the challenge JSON response to force cookie usage:

{
    "configuration": {
        "setCookie": {
            "name": "altcha",
            "path": "/submit"
        }
    },
    "parameters": {},
    "signature": "..."
}

The X-Altcha-Config header must contain a JSON-encoded object with configuration options.

Internationalization (i18n)

ALTCHA supports 50+ languages. You can import individual language translations or a bundle that includes all of them.

Importing Translations

To import all translations:

import 'altcha/i18n/all';

To import specific languages only:

import 'altcha/i18n/de';
import 'altcha/i18n/fr-fr';

Alternatively, you can import the combined bundle, which includes both the widget and all translations:

import 'altcha/i18n';

Language Detection

The widget automatically detects the language from:

  • The <html lang="..."> attribute
  • The user's browser settings (navigator.languages)

To override the language manually, use the `l

Extension points exported contracts — how you extend this code

CollectorOptions (Interface)
(no doc)
src/his.ts
AltchaWidgetJSX (Interface)
(no doc)
src/types/jsx.ts
Option (Interface)
(no doc)
src/playground/types.ts
IntrinsicElements (Interface)
(no doc)
src/types/jsx.ts
Test (Interface)
(no doc)
src/playground/types.ts
AltchaGlobal (Interface)
(no doc)
src/types/index.ts
TestCtx (Interface)
(no doc)
src/playground/types.ts
Configuration (Interface)
(no doc)
src/types/index.ts

Core symbols most depended-on inside this repo

waitForSelector
called by 65
e2e/helpers.ts
hexToBuffer
called by 41
src/helpers.ts
bufferToHex
called by 36
src/helpers.ts
renderWidget
called by 35
e2e/helpers.ts
setCounter
called by 19
src/pow.ts
waitForVerified
called by 13
e2e/helpers.ts
createChallenge
called by 9
src/pow.ts
hash
called by 9
src/helpers.ts

Shape

Function 62
Interface 39
Method 13
Class 9
Enum 3

Languages

TypeScript100%

Modules by API surface

src/types/index.ts28 symbols
src/helpers.ts13 symbols
src/pow.ts10 symbols
src/plugins/obfuscation.plugin.ts10 symbols
src/his.ts8 symbols
src/plugins/base.plugin.ts6 symbols
src/playground/types.ts6 symbols
e2e/helpers.ts5 symbols
vite.helpers.ts4 symbols
src/playground/tests.ts4 symbols
src/types/generic.ts3 symbols
src/server-signature.ts3 symbols

Used by 3 indexed graphs manifest dependencies, hub-wide

For agents

$ claude mcp add altcha \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact