silarhi / cap-bundle
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
Type:symfony-bundle
pkg:composer/silarhi/cap-bundle
Requires
- php: >=8.2
- php-http/discovery: ^1.20.0
- psr/http-client: ^1.0.3
- psr/http-client-implementation: ^1.0
- psr/http-factory: ^1.1
- psr/http-factory-implementation: ^1.0
- symfony/config: ^6.4 || ^7.0 || ^8.0
- symfony/dependency-injection: ^6.4 || ^7.0 || ^8.0
- symfony/form: ^6.4 || ^7.0 || ^8.0
- symfony/http-kernel: ^6.4 || ^7.0 || ^8.0
- symfony/validator: ^6.4 || ^7.0 || ^8.0
Requires (Dev)
- ergebnis/composer-normalize: ^2.54.0
- friendsofphp/php-cs-fixer: ^3.95.27
- nyholm/psr7: ^1.8.2
- phpstan/extension-installer: ^1.4.3
- phpstan/phpstan: ^2.3.2
- phpstan/phpstan-strict-rules: ^2.1.0
- phpstan/phpstan-symfony: ^2.1.1
- phpunit/phpunit: ^11.5.57 || ^12.5.38 || ^13.4.1
- rector/rector: ^2.8.1
- symfony/asset: ^6.4 || ^7.0 || ^8.0
- symfony/asset-mapper: ^6.4 || ^7.0 || ^8.0
- symfony/browser-kit: ^6.4 || ^7.0 || ^8.0
- symfony/css-selector: ^6.4 || ^7.0 || ^8.0
- symfony/error-handler: ^6.4 || ^7.0 || ^8.0
- symfony/framework-bundle: ^6.4 || ^7.0 || ^8.0
- symfony/http-client: ^6.4 || ^7.0 || ^8.0
- symfony/translation: ^6.4 || ^7.0 || ^8.0
- symfony/twig-bundle: ^6.4 || ^7.0 || ^8.0
- twig/twig: ^3.0
Suggests
- symfony/asset: Versions the URL of the bundle's script (bundles/silarhicap/cap.js) like your other assets
- symfony/framework-bundle: Register Silarhi\CapBundle\SilarhiCapBundle for zero-config service wiring
- symfony/http-client: Provides Symfony's psr18.http_client, the default HTTP client calling /siteverify, unless cap.http_client is set
- symfony/translation: Translates the validation messages, which are translation keys (cap.validation.*)
- symfony/twig-bundle: Renders the CapType widget: the bundle adds its form theme to twig.form_themes
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-10-30 17:57:14 UTC
README
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.
Features
- One form field:
CapTyperenders the widget and validates the token on submit, with theCapconstraint - 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 theCapVerifierInterfaceservice 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-clientandnyholm/psr7when 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:
- Installation and configuration reference
- The form type: checkbox and invisible modes, labels and languages
- JavaScript: without a build step, with Stimulus, Symfony Reprise or your bundler, Turbo, Live Components and SPAs
- Self-hosting the widget, Content Security Policy
- Migrating from reCAPTCHA (KarserRecaptcha3Bundle)
- JSON endpoints and DTOs, testing
Contributing
See CONTRIBUTING.md. Release notes are in CHANGELOG.md.
License
Released under the MIT License.