A comprehensive TypeScript library providing both client-side and server-side WebAuthn functionality for implementing passwordless authentication with passkeys and other WebAuthn-compatible authenticators
WebAuthn registration functionality for creating and registering new authenticators (passkeys, security keys, platform authenticators) with support for automatic registration via password manager integration.
Begin authenticator registration via WebAuthn attestation ceremony.
/**
* Begin authenticator "registration" via WebAuthn attestation
* @param options Configuration object containing registration options and settings
* @returns Promise resolving to registration response suitable for server verification
*/
function startRegistration(options: {
optionsJSON: PublicKeyCredentialCreationOptionsJSON;
useAutoRegister?: boolean;
}): Promise<RegistrationResponseJSON>;
type StartRegistrationOpts = Parameters<typeof startRegistration>[0];Parameters:
optionsJSON: Registration options from your server's generateRegistrationOptions() calluseAutoRegister: Optional boolean to attempt silent passkey creation with the password manager the user just signed in with (defaults to false)Usage Examples:
import { startRegistration } from "@simplewebauthn/browser";
// Basic registration
const registrationOptions = await fetch("/webauthn/register/begin").then(r => r.json());
try {
const registrationResponse = await startRegistration({
optionsJSON: registrationOptions,
});
console.log("Registration successful:", registrationResponse);
// Send to server for verification
const verificationResponse = await fetch("/webauthn/register/finish", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(registrationResponse),
});
} catch (error) {
console.error("Registration failed:", error);
}
// Auto-registration with password manager
try {
const registrationResponse = await startRegistration({
optionsJSON: registrationOptions,
useAutoRegister: true, // Try silent passkey creation
});
} catch (error) {
if (error.code === 'ERROR_AUTO_REGISTER_USER_VERIFICATION_FAILURE') {
console.log("Auto-registration failed, user needs manual interaction");
}
}The raw credential returned from navigator.credentials.create().
interface RegistrationCredential extends PublicKeyCredentialFuture {
response: AuthenticatorAttestationResponseFuture;
}
interface PublicKeyCredentialFuture extends PublicKeyCredential {
type: PublicKeyCredentialType;
isConditionalMediationAvailable?(): Promise<boolean>;
parseCreationOptionsFromJSON?(
options: PublicKeyCredentialCreationOptionsJSON,
): PublicKeyCredentialCreationOptions;
parseRequestOptionsFromJSON?(
options: PublicKeyCredentialRequestOptionsJSON,
): PublicKeyCredentialRequestOptions;
toJSON?(): PublicKeyCredentialJSON;
}
interface AuthenticatorAttestationResponseFuture extends AuthenticatorAttestationResponse {
getTransports(): AuthenticatorTransportFuture[];
}JSON-serializable registration response with Base64URL-encoded ArrayBuffers.
/**
* A slightly-modified RegistrationCredential to simplify working with ArrayBuffers that
* are Base64URL-encoded in the browser so that they can be sent as JSON to the server.
*/
interface RegistrationResponseJSON {
id: Base64URLString;
rawId: Base64URLString;
response: AuthenticatorAttestationResponseJSON;
authenticatorAttachment?: AuthenticatorAttachment;
clientExtensionResults: AuthenticationExtensionsClientOutputs;
type: PublicKeyCredentialType;
}
interface AuthenticatorAttestationResponseJSON {
clientDataJSON: Base64URLString;
attestationObject: Base64URLString;
// Optional in L2, but becomes required in L3. Play it safe until L3 becomes Recommendation
authenticatorData?: Base64URLString;
// Optional in L2, but becomes required in L3. Play it safe until L3 becomes Recommendation
transports?: AuthenticatorTransportFuture[];
// Optional in L2, but becomes required in L3. Play it safe until L3 becomes Recommendation
publicKeyAlgorithm?: COSEAlgorithmIdentifier;
publicKey?: Base64URLString;
}Options for WebAuthn registration ceremony.
/**
* A variant of PublicKeyCredentialCreationOptions suitable for JSON transmission to the browser to
* (eventually) get passed into navigator.credentials.create(...) in the browser.
*/
interface PublicKeyCredentialCreationOptionsJSON {
rp: PublicKeyCredentialRpEntity;
user: PublicKeyCredentialUserEntityJSON;
challenge: Base64URLString;
pubKeyCredParams: PublicKeyCredentialParameters[];
timeout?: number;
excludeCredentials?: PublicKeyCredentialDescriptorJSON[];
authenticatorSelection?: AuthenticatorSelectionCriteria;
hints?: PublicKeyCredentialHint[];
attestation?: AttestationConveyancePreference;
attestationFormats?: AttestationFormat[];
extensions?: AuthenticationExtensionsClientInputs;
}
interface PublicKeyCredentialUserEntityJSON {
id: string;
name: string;
displayName: string;
}
interface PublicKeyCredentialDescriptorJSON {
id: Base64URLString;
type: PublicKeyCredentialType;
transports?: AuthenticatorTransportFuture[];
}Registration can throw various WebAuthn-specific errors. Common error scenarios:
browserSupportsWebAuthn() firstimport { startRegistration, WebAuthnError } from "@simplewebauthn/browser";
try {
const response = await startRegistration({ optionsJSON });
} catch (error) {
if (error instanceof WebAuthnError) {
switch (error.code) {
case 'ERROR_CEREMONY_ABORTED':
console.log("User cancelled registration");
break;
case 'ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED':
console.log("This authenticator is already registered");
break;
case 'ERROR_INVALID_DOMAIN':
console.log("Invalid domain for WebAuthn");
break;
default:
console.log(`Registration error: ${error.code}`);
}
}
}Install with Tessl CLI
npx tessl i tessl/npm-simplewebauthn--browser