biokey-core
Low-level WebAuthn + key derivation primitives
biokey-js
High-level browser SDK with localStorage and optional server sync
biokey-react
React hook wrapping
biokey-jsbiokey-server
Bun + Hono authentication server with SQLite
biokey-core
Core library for WebAuthn enrollment, authentication, and key derivation. Use this if you want full control or need to build custom integrations.Install
Usage
Exports
| Export | Description |
|---|---|
BioKey | Main class for enrollment and authentication |
enroll(rpId, rpName) | Standalone enrollment function |
authenticate(identity, rpId) | Standalone authentication function |
deriveKey(rawId) | HKDF-SHA256 key derivation (V1 fallback) |
extractPRFOutput(credential) | Extract PRF secret from WebAuthn credential |
isPRFSupported() | Check if platform supports PRF extension |
bufToHex(buffer) | Convert ArrayBuffer to hex string |
hexToBuf(hex) | Convert hex string to ArrayBuffer |
PRF_SALT | PRF salt constant ("biokey-prf-v2-salt") |
When to use: Building a custom client, integrating with non-browser environments, or researching the protocol.
biokey-js
Browser SDK with localStorage persistence and optional server sync. Recommended for most web applications.Install
Usage
API Reference
Constructor Options
| Option | Type | Default | Description |
|---|---|---|---|
rpId | string | location.hostname | Relying party ID (must match domain) |
rpName | string | 'BioKey' | Display name shown during enrollment |
serverUrl | string | null | null | Optional biokey-server URL for cross-device auth |
Methods
| Method | Returns | Description |
|---|---|---|
enroll(userId?) | Promise<Identity> | Trigger fingerprint enrollment |
authenticate(userId?) | Promise<{ verified, publicKey }> | Verify fingerprint |
getIdentity() | Identity | null | Retrieve stored identity from localStorage |
clearIdentity() | void | Remove stored identity |
Identity Type
When to use: Production web apps, SPAs, or any project that needs localStorage-backed identity management.
biokey-react
React hook for BioKey. Wrapsbiokey-js with state management.
Install
Usage
Hook Options
| Option | Type | Default | Description |
|---|---|---|---|
rpId | string | location.hostname | Relying party ID |
rpName | string | 'BioKey' | Display name |
serverUrl | string | null | null | Optional server URL |
Return Values
| Value | Type | Description |
|---|---|---|
identity | Identity | null | Stored identity object |
status | string | idle | enrolling | enrolled | authenticating | authenticated | error |
error | string | null | Error message from last operation |
isEnrolled | boolean | Whether an identity exists |
isLoading | boolean | True during enrollment or authentication |
enroll(userId?) | function | Start enrollment flow |
authenticate(userId?) | function | Start authentication flow |
reset() | function | Clear stored identity |
When to use: React apps (Next.js, Vite, CRA) where you want declarative state management.
biokey-server
Authentication server built with Bun, Hono, and SQLite. Provides challenge issuance, enrollment, and verification endpoints.Install
The server is a standalone package, not a library:Run Locally
Environment Variables
| Variable | Default | Description |
|---|---|---|
PORT | 3000 | Server port |
DATABASE_PATH | ./biokey.db | SQLite database file path |
Endpoints
See the Server API Reference for full endpoint documentation.| Method | Endpoint | Description |
|---|---|---|
GET | /challenge | Generate a single-use authentication challenge |
POST | /enroll | Register a new identity public key |
POST | /verify | Verify a challenge with a userId |
Deploy
The server uses an in-memory SQLite database by default. For production, configure a persistent volume or use a managed database.
When to use: You need cross-device authentication, multi-session support, or server-side identity verification.
Framework-Specific Setup
Next.js (App Router)
app/components/BioKeyAuth.tsx
Vite + React
Vanilla JavaScript (no framework)
index.html:
main.js:
Browser Compatibility
BioKey relies on WebAuthn and Web Crypto APIs:| Browser | Min Version | PRF Support | Notes |
|---|---|---|---|
| Chrome | 100+ | ✅ Android | Full support |
| Safari | 16+ | ⚠️ 18+ only | PRF in Safari 18+, falls back to V1 on older versions |
| Firefox | 119+ | ❌ Fallback | Uses rawId-HKDF (V1) |
| Edge | 100+ | ✅ Windows | Full support with Windows Hello |
Troubleshooting
Error: 'NotAllowedError: The operation either timed out or was not allowed'
Error: 'NotAllowedError: The operation either timed out or was not allowed'
Cause: User canceled the biometric prompt or the authenticator timed out.Solution: Retry the operation. Ensure the timeout is set to at least 60 seconds (default in BioKey).
Error: 'SecurityError: The operation is insecure'
Error: 'SecurityError: The operation is insecure'
Cause: WebAuthn requires HTTPS or
localhost.Solution: Use https:// or deploy to a hosting platform (Vercel, Netlify, Railway) for testing.PRF not supported — falling back to V1
PRF not supported — falling back to V1
Cause: Platform doesn’t support the WebAuthn PRF extension.Solution: This is expected. BioKey automatically falls back to rawId-HKDF (V1). The identity will still work.
Key mismatch error during authentication
Key mismatch error during authentication
Cause: The derived key doesn’t match the stored
publicKey.Solution:- Different device: Each device produces a unique identity. Use the server for cross-device auth.
- Credential deleted: The authenticator credential was removed. Re-enroll.
- Browser storage cleared: localStorage was wiped. Re-enroll.
Next Steps
Quickstart
Build your first BioKey integration in 5 minutes
How It Works
Understand PRF, rawId-HKDF, and key derivation
Server Setup
Deploy biokey-server for cross-device auth
Examples
Explore full code examples