SimpleWebAuthn Browser
Browser-side WebAuthn client for passkey registration, authentication, and feature detection in web apps.
Repository Health
Technical Analysis
@simplewebauthn/browser is the client-side half of the SimpleWebAuthn project, a TypeScript-first pair of libraries (alongside @simplewebauthn/server) that simplifies integrating the W3C WebAuthn standard and passkeys into web applications. It wraps the browser’s native Credential Management API, converting the base64url-encoded JSON options produced by @simplewebauthn/server’s generateRegistrationOptions()/generateAuthenticationOptions() into the ArrayBuffer-based structures navigator.credentials.create()/get() expect, then converts the resulting credential back into JSON-safe output ready to POST to a server for verification.
Beyond the core startRegistration()/startAuthentication() ceremony helpers, the package exposes feature-detection utilities (browserSupportsWebAuthn(), browserSupportsPasskeys(), getBrowserCapabilities()) so applications can conditionally show passkey UI, a WebAuthnAbortService singleton to cancel an in-flight ceremony when a user starts a new one, and typed error identification that turns opaque browser DOMExceptions into a WebAuthnError with a stable, spec-referenced error code. It ships as ESM/CJS for Node and Deno and as UMD bundles (ES2021 and a polyfilled ES5 build) for direct <script> tag use via unpkg, with zero runtime dependencies.
What You Get
- Ceremony helpers - startRegistration() and startAuthentication() convert server-generated JSON options to/from the browser’s native Credential Management API in one call each.
- Feature detection - browserSupportsWebAuthn(), browserSupportsPasskeys(), browserSupportsWebAuthnAutofill(), and getBrowserCapabilities() gate UI on what the current browser/authenticator actually supports.
- Typed error identification - identifyRegistrationError()/identifyAuthenticationError() translate raw DOMExceptions into a WebAuthnError with a stable, spec-referenced error code.
- Multiple build targets - ESM/CJS for Node and Deno plus ES2021 and ES5 UMD bundles for direct browser <script> tag use via unpkg.
- Ceremony cancellation - a WebAuthnAbortService singleton automatically aborts an in-flight registration/authentication when a new one starts.
Common Use Cases
- Passwordless login forms - replacing password fields with a “Sign in with a passkey” button that calls startAuthentication().
- Passkey enrollment flows - prompting a signed-in user to register a passkey via startRegistration() after a successful password or OTP login.
- Progressive WebAuthn rollout - using browserSupportsWebAuthn()/getBrowserCapabilities() to show passkey UI only where it’s supported, falling back gracefully elsewhere.
- Autofill-based passkey sign-in - pairing conditional UI mediation with browserSupportsWebAuthnAutofill() to surface passkeys directly in the browser’s autofill dropdown.
Under The Hood
Architecture The browser package lives inside a Deno-native workspace monorepo (packages/browser, packages/server, packages/types) that shares a common types package across client and server. Within packages/browser, the public surface is deliberately narrow: methods/ holds the three exported ceremony functions (startRegistration, startAuthentication, sendSignal), helpers/ holds encoding (base64URLStringToBuffer/bufferToBase64URLString), capability detection (getBrowserCapabilities, browserSupportsWebAuthn), and error translation (identifyRegistrationError, identifyAuthenticationError), and index.ts re-exports all of it flat. Concurrency across ceremonies is centralized in a single WebAuthnAbortService singleton that aborts any prior in-flight navigator.credentials call before starting a new one, and error handling is centralized in identifyRegistrationError/identifyAuthenticationError, which map a raw DOMException’s name plus the original request options (e.g. authenticatorSelection, mediation) onto a typed WebAuthnError carrying a spec-referenced error code rather than letting callers parse browser-specific error strings.
Tech Stack The repo is TypeScript-first and Deno-native (a deno.json workspace, targeting Deno 2.4+), but ships to consumers as a conventional npm package: a build_npm.ts script uses @deno/dnt (Deno-to-Node transform) to generate ESM/CJS output, then Rollup (with @rollup/plugin-terser, @rollup/plugin-babel, rollup-plugin-version-injector) produces UMD bundles for two browser targets - an ES2021 build and a Babel-polyfilled ES5 build for legacy browsers - published to unpkg. The generated package.json declares zero runtime dependencies; everything the library needs is either native browser API (Credential Management, PublicKeyCredential) or bundled at build time.
Code Quality
Tests run on Deno’s native test runner (Deno.test with @std/assert/@std/testing) rather than a Node test framework, with roughly one test file per two source files covering the encoding helpers, capability detection, and every exported method (startAuthentication.test.ts, startRegistration.test.ts, sendSignal.test.ts, plus dedicated helper tests). Errors are explicit and typed - a custom WebAuthnError class carries a discriminated code field referencing the exact WebAuthn spec step that produced it, rather than surfacing raw browser exceptions. CI (ciChecks.yml) runs the full test suite across a matrix of multiple Node LTS versions and multiple Deno minor versions on every push and pull request, and the workspace enforces consistent formatting via deno fmt.
API Design
The two primary entry points, startRegistration() and startAuthentication(), each take a single { optionsJSON, ... } object that mirrors the shape @simplewebauthn/server’s generate*Options() already returns, so integrating the two packages requires close to no glue code; a defensive compatibility shim even detects the old positional-argument calling convention, warns, and auto-corrects it rather than throwing. Feature detection is exposed as small, independently callable functions (browserSupportsWebAuthn(), browserSupportsPasskeys(), getBrowserCapabilities()) so consumers can build progressive-enhancement UI without importing the whole ceremony surface, and every thrown error arrives pre-classified via identifyRegistrationError()/identifyAuthenticationError() instead of requiring consumers to inspect DOMException internals themselves.
Used by 28 apps in this directory
Authelia
Security · Authentication
OpenID Certified SSO and MFA portal for securing self-hosted web applications behind reverse proxies.
Craft CMS
CMS
A developer-first PHP CMS with clean-slate content modeling, auto-generated GraphQL API, and a four-tier edition system that scales from solo projects to enterprise deployments.
Documenso
Digital Signiture
Self-hosted, open-source DocuSign alternative with legally binding PDF signatures, multi-party workflows, and a full REST and tRPC API.
Documenso
Digital Signiture
Self-hosted, open-source DocuSign alternative with legally binding PDF signatures, multi-party workflows, and a full REST and tRPC API.
Ghostfolio
Invoicing Finance
Track your stocks, ETFs, and crypto with a privacy-first, self-hostable wealth management platform built for data-driven investors.
Ghostfolio
Invoicing Finance
Track your stocks, ETFs, and crypto with a privacy-first, self-hostable wealth management platform built for data-driven investors.
Infisical
Security · Devops
The open-source platform for secrets, certificates, privileged access, and AI agent security — all in one self-hostable system.
Infisical
Security · Devops
The open-source platform for secrets, certificates, privileged access, and AI agent security — all in one self-hostable system.
LLM Gateway
AI Development · Devops
One API endpoint for 25+ LLM providers — route, track costs, enforce compliance, and switch models without changing your code.