
Security News
The Changelog Podcast: Practical Steps to Stay Safe on npm
Learn the essential steps every developer should take to stay secure on npm and reduce exposure to supply chain attacks.
@jaw.id/passkeys
Advanced tools
A minimal TypeScript package for passkey management with configurable backend support. Use the default JAW passkey service or self-host your own compatible server.
import { configurePasskeys, createPasskey, loginWithPasskey } from '@jaw.id/passkeys'
// Configure for JAW service (requires API key)
configurePasskeys({
apiKey: 'your-justaname-api-key'
})
// Or configure for custom server (no API key needed)
configurePasskeys({
serverUrl: 'https://your-passkey-server.com/api/passkeys'
})
'cross-platform' (default) or 'app-specific'
cross-platform: Uses a popup-based flow for passkey management across different applicationsapp-specific: Uses native WebAuthn API directly for app-specific passkeysThe package supports two modes for passkey creation and authentication:
This is the default mode that allows passkeys to be shared across different applications:
keys.jaw.idconfigurePasskeys({
mode: 'cross-platform', // This is the default
apiKey: 'your-api-key'
})
For applications that need isolated passkey management:
configurePasskeys({
mode: 'app-specific',
apiKey: 'your-api-key'
})
The package validates configuration automatically:
If you wish to run your own passkey server, it must implement the following endpoints and data structures to be compatible:
/ - Lookup Passkeys by Credential IDsRetrieves passkey information for one or more credential IDs.
Query Parameters:
credentialIds (string[], repeatable): Array of credential IDs to lookupResponse Format:
{
"statusCode": 200,
"result": {
"data": {
"passkeys": [
{
"credentialId": "string",
"publicKey": "0x...",
"displayName": "string"
}
]
},
"error": null
}
}
Note: publicKey must be hex-encoded with 0x prefix.
Error Response (404):
{
"statusCode": 404,
"result": {
"data": null,
"error": "Passkeys not found"
}
}
/ - Register a New PasskeyRegisters a new passkey credential.
Request Body:
{
"credentialId": "string",
"publicKey": "0x...",
"displayName": "string"
}
Note: publicKey must be hex-encoded with 0x prefix.
Headers:
Content-Type: application/jsonResponse:
0xWhen implementing your own passkey server:
const express = require('express');
const app = express();
// In-memory storage (use a proper database in production)
const passkeys = new Map();
// Lookup passkeys
app.get('/api/passkeys', (req, res) => {
const credentialIds = req.query.credentialIds || [];
const ids = Array.isArray(credentialIds) ? credentialIds : [credentialIds];
const foundPasskeys = ids
.map(id => passkeys.get(id))
.filter(Boolean);
if (foundPasskeys.length === 0) {
return res.status(404).json({
statusCode: 404,
result: {
data: null,
error: 'Passkeys not found'
}
});
}
res.json({
statusCode: 200,
result: {
data: {
passkeys: foundPasskeys
},
error: null
}
});
});
// Register passkey
app.post('/api/passkeys', express.json(), (req, res) => {
const { credentialId, publicKey, displayName } = req.body;
if (!credentialId || !publicKey || !displayName) {
return res.status(400).json({
statusCode: 400,
result: {
data: null,
error: 'Missing required fields'
}
});
}
passkeys.set(credentialId, {
credentialId,
publicKey,
displayName
});
res.status(201).send();
});
app.listen(3000);
import { createPasskey } from '@jaw.id/passkeys'
try {
const passkey = await createPasskey('My Passkey')
console.log('Created passkey:', passkey.id)
} catch (error) {
console.error('Failed to create passkey:', error)
}
import { loginWithPasskey, loginWithSpecificPasskey } from '@jaw.id/passkeys'
// Login with native passkey selector
const passkey = await loginWithPasskey()
// Login with specific passkey ID
const specificPasskey = await loginWithSpecificPasskey('credential-id')
import {
checkAuth,
storePasskeyAccount,
fetchAccountsFromLocalStorage
} from '@jaw.id/passkeys'
// Check authentication status
const authResult = await checkAuth()
console.log('Is authenticated:', authResult.isAuthenticated)
// Get stored accounts
const accounts = fetchAccountsFromLocalStorage()
To verify your server is compatible:
configurePasskeys()If no configuration is provided, the package defaults to the JAW passkey service at https://api.justaname.id/wallet/v2/passkeys. When using the default service, you must provide an API key:
configurePasskeys({
apiKey: 'your-justaname-api-key'
})
FAQs
TypeScript package for WebAuthn passkey management
The npm package @jaw.id/passkeys receives a total of 2 weekly downloads. As such, @jaw.id/passkeys popularity was classified as not popular.
We found that @jaw.id/passkeys demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Learn the essential steps every developer should take to stay secure on npm and reduce exposure to supply chain attacks.

Security News
Experts push back on new claims about AI-driven ransomware, warning that hype and sponsored research are distorting how the threat is understood.

Security News
Ruby's creator Matz assumes control of RubyGems and Bundler repositories while former maintainers agree to step back and transfer all rights to end the dispute.