Skip to main content
BioKey provides four packages, each serving a different part of the authentication flow:

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-js

biokey-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

npm install biokey-core

Usage

import { BioKey } from 'biokey-core'

const biokey = new BioKey({
  rpId: location.hostname,
  rpName: 'My App'
})

// Enroll
const identity = await biokey.enroll()
// → { publicKey, credentialId, enrolledAt, method }

// Authenticate
const result = await biokey.authenticate(identity)
// → { verified: true, publicKey, method }

Exports

ExportDescription
BioKeyMain 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_SALTPRF 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

npm install biokey-js

Usage

import { BioKeyClient } from 'biokey-js'

const biokey = new BioKeyClient()

await biokey.enroll()
await biokey.authenticate()

API Reference

Constructor Options

OptionTypeDefaultDescription
rpIdstringlocation.hostnameRelying party ID (must match domain)
rpNamestring'BioKey'Display name shown during enrollment
serverUrlstring | nullnullOptional biokey-server URL for cross-device auth

Methods

MethodReturnsDescription
enroll(userId?)Promise<Identity>Trigger fingerprint enrollment
authenticate(userId?)Promise<{ verified, publicKey }>Verify fingerprint
getIdentity()Identity | nullRetrieve stored identity from localStorage
clearIdentity()voidRemove stored identity

Identity Type

{
  publicKey: string      // 64-char hex identity key
  credentialId: string   // Hex-encoded WebAuthn credential ID
  deviceId: string       // 16-char hex device fingerprint
  enrolledAt: number     // Unix timestamp (ms)
  method: 'prf' | 'rawid'  // Key derivation method
}
When to use: Production web apps, SPAs, or any project that needs localStorage-backed identity management.

biokey-react

React hook for BioKey. Wraps biokey-js with state management.

Install

npm install biokey-react
Peer dependency: Requires React 18+. Install react separately if not already in your project.

Usage

import { useBioKey } from 'biokey-react'

export function LoginButton() {
  const { 
    identity, 
    status, 
    error, 
    isEnrolled, 
    isLoading, 
    enroll, 
    authenticate, 
    reset 
  } = useBioKey({
    serverUrl: 'https://your-biokey-server.railway.app'
  })

  if (!isEnrolled) {
    return (
      <button onClick={() => enroll('user-123')} disabled={isLoading}>
        {isLoading ? 'Scanning...' : 'Enroll Fingerprint'}
      </button>
    )
  }

  return (
    <div>
      <p>Identity: {identity.publicKey.slice(0, 16)}...</p>
      <button onClick={() => authenticate('user-123')} disabled={isLoading}>
        {isLoading ? 'Verifying...' : 'Authenticate'}
      </button>
      <button onClick={reset}>Reset</button>
      {error && <p style={{ color: 'red' }}>{error}</p>}
    </div>
  )
}

Hook Options

OptionTypeDefaultDescription
rpIdstringlocation.hostnameRelying party ID
rpNamestring'BioKey'Display name
serverUrlstring | nullnullOptional server URL

Return Values

ValueTypeDescription
identityIdentity | nullStored identity object
statusstringidle | enrolling | enrolled | authenticating | authenticated | error
errorstring | nullError message from last operation
isEnrolledbooleanWhether an identity exists
isLoadingbooleanTrue during enrollment or authentication
enroll(userId?)functionStart enrollment flow
authenticate(userId?)functionStart authentication flow
reset()functionClear 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:
git clone https://github.com/Cryptoistaken/BioAuth.git
cd BioAuth/packages/biokey-server
bun install

Run Locally

bun run dev
# Server runs on http://localhost:3000

Environment Variables

VariableDefaultDescription
PORT3000Server port
DATABASE_PATH./biokey.dbSQLite database file path

Endpoints

See the Server API Reference for full endpoint documentation.
MethodEndpointDescription
GET/challengeGenerate a single-use authentication challenge
POST/enrollRegister a new identity public key
POST/verifyVerify a challenge with a userId

Deploy

# Install Railway CLI
npm i -g @railway/cli

# Login and deploy
railway login
railway up
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)

npx create-next-app@latest my-biokey-app
cd my-biokey-app
npm install biokey-react
Create a client component:
app/components/BioKeyAuth.tsx
'use client'

import { useBioKey } from 'biokey-react'

export function BioKeyAuth() {
  const { isEnrolled, enroll, authenticate } = useBioKey()
  // ... your component logic
}

Vite + React

npm create vite@latest my-biokey-app -- --template react
cd my-biokey-app
npm install biokey-react
npm run dev

Vanilla JavaScript (no framework)

mkdir my-biokey-app && cd my-biokey-app
npm init -y
npm install biokey-js
Create index.html:
<!DOCTYPE html>
<html>
  <head>
    <title>BioKey Demo</title>
  </head>
  <body>
    <button id="enroll">Enroll</button>
    <button id="auth">Authenticate</button>
    <script type="module" src="/main.js"></script>
  </body>
</html>
Create main.js:
import { BioKeyClient } from 'biokey-js'

const biokey = new BioKeyClient()

document.getElementById('enroll').onclick = async () => {
  const identity = await biokey.enroll()
  console.log('Enrolled:', identity)
}

document.getElementById('auth').onclick = async () => {
  const result = await biokey.authenticate()
  console.log('Authenticated:', result)
}

Browser Compatibility

BioKey relies on WebAuthn and Web Crypto APIs:
BrowserMin VersionPRF SupportNotes
Chrome100+✅ AndroidFull support
Safari16+⚠️ 18+ onlyPRF in Safari 18+, falls back to V1 on older versions
Firefox119+❌ FallbackUses rawId-HKDF (V1)
Edge100+✅ WindowsFull support with Windows Hello
HTTPS required: WebAuthn requires a secure context (HTTPS or localhost). Development over HTTP will fail.

Troubleshooting

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).
Cause: WebAuthn requires HTTPS or localhost.Solution: Use https:// or deploy to a hosting platform (Vercel, Netlify, Railway) for testing.
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.
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

Build docs developers (and LLMs) love