Installation
The Symfony UX Initiative enables high-interaction applications directly from Twig templates without writing custom JavaScript. The WebAuthn Stimulus Controller makes implementing passwordless authentication as simple as adding a few Twig functions to your forms.
Prerequisites
Before installing the Stimulus Controller, you need:
Symfony UX configured — follow the official Symfony UX documentation
WebAuthn Bundle installed — see Symfony Bundle Installation
Installation
Since v5.3.0 the Stimulus controllers are published on npm as @web-auth/webauthn-stimulus. The npm package is the canonical and only maintained source going forward — the legacy web-auth/webauthn-stimulus Composer package is deprecated and will be removed in 6.0.0.
Do not declare this package in assets/controllers.json. That file is reserved for Symfony PHP UX packages. Symfony\UX\StimulusBundle resolves every entry against an installed Composer package, so adding @web-auth/webauthn-stimulus there throws Could not find package "web-auth/webauthn-stimulus" referred to from controllers.json as soon as the Composer wrapper is gone (the very thing we want). Register the controllers from your JavaScript code instead — see below.
1. Pin the package in your importmap
With Symfony AssetMapper:
php bin/console importmap:require @web-auth/webauthn-stimulusWith Webpack Encore, Vite, esbuild or any other bundler:
npm install @web-auth/webauthn-stimulusThe package depends on @hotwired/stimulus and @simplewebauthn/browser, which are pulled in automatically by AssetMapper or your bundler.
2. Register the controllers in your Stimulus app
Import the controllers from the package entry point and register them on your Stimulus Application. Use the same ---separated identifiers that stimulus_controller('@web-auth/webauthn-stimulus/...') produces, so the existing Twig helpers keep working unchanged:
Why these identifiers? stimulus_controller('@vendor/pkg/ctrl') simply transforms the name to a flat string by stripping the leading @ and turning / into --. So stimulus_controller('@web-auth/webauthn-stimulus/authentication') renders data-controller="web-auth--webauthn-stimulus--authentication" — the same identifier you registered in JS. Existing Twig templates that use the @-prefixed form keep working without changes.
The exact location of your Stimulus bootstrap file depends on your project layout. With the default Symfony AssetMapper recipe it is assets/bootstrap.js or assets/app.js. Anywhere your Application.start() runs is fine.
Deprecated: install via Composer (web-auth/webauthn-stimulus)
web-auth/webauthn-stimulus)This installation path is kept for backward compatibility only. New projects should use the npm package above.
This command installs the PHP wrapper, which used to register the Stimulus controllers via Symfony Flex and configure AssetMapper to import them from a vendored copy. As of v5.3.0 the same JavaScript ships on npm and the PHP wrapper no longer brings any added value — it is scheduled for removal in 6.0.0.
What's Included
The package provides Stimulus controllers that handle:
Registration flows — calls
navigator.credentials.create()for youAuthentication flows — calls
navigator.credentials.get()for youBase64 encoding/decoding — automatically handles data conversion
Error handling — gracefully handles common WebAuthn errors
Browser autofill — supports conditional UI for passkey selection
Conditional create (v5.3.0+) — enhanced conditional UI support for both registration and authentication
PRF extension — built-in support for the Pseudo-Random Function extension
Three controllers ship in the package:
WebauthnController— combined controller (legacy, still supported)AuthenticationController— dedicated authentication controllerRegistrationController— dedicated registration controller
The dedicated controllers offer better separation of concerns, enhanced conditional UI support, and improved error handling. The combined controller remains available for backward compatibility.
Basic Usage
Once the controllers are registered, you can use them in your Twig templates with the standard Symfony UX helpers:
stimulus_controller()— attaches a controller to your formstimulus_action()— triggers WebAuthn operations on button clicksstimulus_target()— marks an input as a controller target
The first argument is the package-prefixed name — it will resolve to the ---separated identifier you registered in step 2.
Registration Form Example
Authentication Form Example
Controller Options
The dedicated controllers accept the following options. See the User Authentication and User Registration pages for the full list of values, targets, actions and events.
Registration Options
optionsUrl
string
/registration/options
URL to fetch creation options
resultUrl
string
/registration/verify
URL to submit the attestation response
submitViaForm
boolean
false
Submit via form instead of fetch
successRedirectUri
string
–
URL to redirect after successful registration
autoRegister
boolean
false
Auto-start registration on page load
Authentication Options
optionsUrl
string
/authentication/options
URL to fetch assertion options
resultUrl
string
/authentication/verify
URL to submit the assertion response
submitViaForm
boolean
false
Submit via form instead of fetch
successRedirectUri
string
–
URL to redirect after successful auth
conditionalUi
boolean
false
Enable conditional UI (autofill)
Troubleshooting
Could not find package "web-auth/webauthn-stimulus" referred to from controllers.json
Could not find package "web-auth/webauthn-stimulus" referred to from controllers.jsonYou added @web-auth/webauthn-stimulus to assets/controllers.json. Remove that entry. The npm package is not a Symfony UX PHP package — controllers.json is wrong here. Register the controllers from your JS bootstrap file instead, as shown in step 2 above.
Controller not found
If you see "application Error: Controller 'web-auth--webauthn-stimulus--authentication' is not registered" (or similar):
Verify the identifier in
app.register('web-auth--webauthn-stimulus--authentication', ...)matches the rendereddata-controllerattribute. Rememberstimulus_controller('@web-auth/webauthn-stimulus/authentication')producesdata-controller="web-auth--webauthn-stimulus--authentication".Make sure your bootstrap file is included by your importmap (
{{ importmap('app') }}in your base template).Clear Symfony cache:
php bin/console cache:clear.
JavaScript errors
If you see console errors:
Ensure you're using HTTPS (required for WebAuthn).
Check browser console for specific error messages.
Verify WebAuthn routes are properly configured in
config/routes/webauthn.yaml.Ensure the controller is loaded by checking the browser's network tab.
HTTPS Requirement
WebAuthn requires HTTPS to function. For development, use the Symfony CLI for automatic HTTPS:
For production, ensure HTTPS is properly configured on your web server.
Next Steps
Now that the Stimulus Controller is installed, proceed to:
User Registration — create registration forms
User Authentication — implement login flows
Additional Authenticators — allow users to register backup devices
See Also
Symfony UX Documentation — official UX guide
Stimulus Documentation — Stimulus framework reference
WebAuthn Bundle — backend configuration
JavaScript Integration — manual JavaScript implementation
Last updated
Was this helpful?