Search by

silarhi / cap-bundle

guillaume-sainthillier

Cap CAPTCHA (trycap.dev) for Symfony forms: a self-hosted, proof-of-work reCAPTCHA alternative with a form type, a validator constraint and a Turbo-ready widget

Package info

github.com/silarhi/cap-bundle

Homepage

Documentation

Type:symfony-bundle

pkg:composer/silarhi/cap-bundle

Statistics

Installs: 307

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 1

v0.4.0 2026-10-29 22:25 UTC

README

License PHP Version CI Status Coverage JavaScript coverage

Cap Bundle

Cap CAPTCHA (trycap.dev), the self-hosted proof-of-work CAPTCHA, in your Symfony forms.
A form type, a validator constraint and a widget that keeps working across Turbo visits — the KarserRecaptcha3Bundle way, without Google.

📖 Documentation

Features

  • One form field: CapType renders the widget and validates the token on submit, with the Cap constraint
  • Checkbox or invisible: Cap's widget, or nothing at all: the challenge is solved while the visitor fills the form
  • SPA ready: a framework-agnostic core for any SPA, the back-forward cache and forms you submit with fetch(), plus opt-in adapters for Turbo Drive and Live Components
  • Stimulus or not: a controller StimulusBundle or Symfony Reprise registers for you, or a script the form renders, with no build step
  • Self-hosted end to end: your Cap server, and the widget script and its WebAssembly solver from your domain if you like
  • Fails closed: a Cap server out of reach rejects the submission, and the error stays on the field
  • Any payload: the #[Cap] constraint and the CapVerifierInterface service protect JSON endpoints too

Requirements

  • PHP 8.2+
  • Symfony 6.4, 7.x or 8.x
  • A PSR-18 HTTP client and a PSR-17 implementation: Composer installs symfony/http-client and nyholm/psr7 when the application has none (php-http/discovery), or set your own client
  • A Cap Standalone server, and a site key created in its dashboard

Installation

composer require silarhi/cap-bundle
# .env
CAP_ENDPOINT=https://cap.example.com/<site-key>/
CAP_SECRET_KEY=<the secret key of the site key>
# config/packages/cap.yaml
when@test:
    cap:
        enabled: false

Quick start

use Silarhi\CapBundle\Form\CapType;

$builder
    ->add('message', TextareaType::class)
    ->add('captcha', CapType::class);

{{ form(form) }} renders the widget and its script. On submit, the token is redeemed against your Cap server: a missing or rejected one is a form error on the field.

Documentation

Everything else is on cap-bundle.silarhi.dev:

Contributing

See CONTRIBUTING.md. Release notes are in CHANGELOG.md.

License

Released under the MIT License.