Cap is a free, open-source, self-hosted CAPTCHA replacement that swaps visual puzzles for proof-of-work and instrumentation challenges, built for developers and site operators who want anti-bot protection without shipping their visitors' data to a third-party service.
What it is
Cap is a lightweight JavaScript project in the Security & Privacy / Application Security category, distributed as the @cap.js/wasm npm package and, in its default configuration, run as a Standalone Docker container that bundles analytics and the rest of the server-side machinery. It sits in the same slot as a CAPTCHA widget on a login form, a signup page, or any endpoint that scraper and bot traffic tends to reach. The project describes itself as modern, fast, simple to integrate, and free of dependencies, and it carries the anti-abuse, anti-bot, anti-scraper, antispam and defense topics to match that positioning.
The concrete thing it replaces is the visual CAPTCHA: the image grid, the distorted text, the "select all traffic lights" puzzle. That model costs users time, depends on a third-party script loading in the browser, and typically involves some form of challenge telemetry going back to the vendor. Cap instead issues proof-of-work and instrumentation challenges. The visitor's browser does the work, the widget can be hidden entirely, and challenges can be solved in the background with no interaction from the user. Nothing is sent back to Cap's servers, no images are involved, and the client-side payload is roughly 20kb — the README claims that is 250 times smaller than hCaptcha, with load times measured in milliseconds.
Key capabilities
- Proof-of-work challenges and instrumentation challenges replace image-based puzzles entirely, so visitors never solve a visual task.
- Standalone mode runs Cap anywhere as a Docker container, and that mode includes analytics.
- No user interaction is required: the widget can be hidden and the challenge solved in the background.
- Privacy-first by design — Cap sends no telemetry back to its own servers.
- Fully customizable through CSS variables covering colors, size, position and icons.
- Small client footprint of about 20kb with zero dependencies, loading in milliseconds.
- Open-source under the Apache 2.0 license, with an OpenSSF Best Practices gold badge and the
@cap.js/wasm package published to npm and served through jsDelivr.
Who uses it and how
- Site operators replacing reCAPTCHA, hCaptcha or Cloudflare Turnstile on login, signup and form endpoints, where a CAPTCHA widget is already expected to load.
- Teams that need anti-bot protection but cannot send visitor data to an outside vendor, and therefore run the Docker container inside their own infrastructure.
- Deployments that want minimal integration work, using the documented npm package and guides at trycap.dev alongside the published demo.
- Smaller teams and individual projects that would rather run one standalone container than operate a multi-service stack, using the container's built-in analytics instead of a separate dashboard.
- Anyone who wants a challenge that stays invisible: the widget is hidden and the proof-of-work is computed without the user noticing.
Getting started
The default path is the Standalone Docker container, with the documentation at trycap.dev, a hosted demo, and a one-click Railway deploy template as the alternatives. The client side is distributed as the @cap.js/wasm npm package.
How it compares
reCAPTCHA, hCaptcha and Cloudflare Turnstile are hosted services run by Google, hCaptcha and Cloudflare respectively, while Cap is Apache-2.0 licensed and self-hosted. That difference decides where data goes: Cap's README states it sends no telemetry back to its servers, so the challenge traffic stays on infrastructure the operator controls. It also means there is no vendor account or per-request service relationship in the loop — the operator runs the container and owns the result.
When to use it — and when not to
A self-hoster has to operate the Docker container and whatever backing services the deployment needs, and the README does not spell out that operational surface in any detail, so expect to read the documentation site rather than the repository. The registry lists the license as NOASSERTION even though the README states Apache 2.0, and that mismatch is worth confirming before any formal compliance review. Teams that want a zero-ops, vendor-hosted challenge with a support contract should not pick this; teams willing to run one container and read the docs should.