Package Exports
- @sourceregistry/node-jwt
- @sourceregistry/node-jwt/promises
Readme
๐ @sourceregistry/node-jwt
A minimal, secure, and production-ready JWT (JSON Web Token) library for Node.js with zero dependencies. Supports all standard signing algorithms (HMAC, RSA, ECDSA, EdDSA, RSASSA-PSS) and full claim validation.
โจ Why another JWT library?
Most JWT libraries are bloated, have security pitfalls, or lack proper TypeScript support. This library is:
- Tiny
- Secure by default (correct ECDSA/RSA/PSS/EdDSA encoding, time validation, algorithm whitelisting)
- TypeScript-first with full JSDoc
- No external dependencies
- 100% test coverage
- Dual API: Sync and Promise-based
๐ฆ Installation
npm install @sourceregistry/node-jwtRequires Node.js โฅ 16
๐ Quick Start
Sync API (default)
import { sign, verify, decode } from '@sourceregistry/node-jwt';
// Sign
const token = sign(
{ sub: '1234567890', name: 'John Doe', iat: Math.floor(Date.now() / 1000) },
'your-secret-key',
{ alg: 'HS256' }
);
// Verify
const result = verify(token, 'your-secret-key', { issuer: 'https://example.com' });
if (result.valid) {
console.log('Payload:', result.payload);
} else {
console.error('JWT Error:', result.error.code, result.error.reason);
}
// Decode (unsafe)
const { header, payload, signature } = decode(token);Promise API (/promises)
import { sign, verify, decode } from '@sourceregistry/node-jwt/promises';
// Sign
const token = await sign(
{ sub: '1234567890', name: 'John Doe', iat: Math.floor(Date.now() / 1000) },
'your-secret-key',
{ alg: 'HS256' }
);
// Verify
try {
const { payload, header, signature } = await verify(token, 'your-secret-key', {
issuer: 'https://example.com',
audience: 'my-app',
algorithms: ['HS256']
});
console.log('Payload:', payload);
} catch (error) {
console.error('JWT Error:', error.code, error.reason);
}
// Decode (unsafe)
const { header, payload, signature } = await decode(token);๐ Supported Algorithms
| Algorithm | Type | Secret Type |
|---|---|---|
| HS256 | HMAC | string | Buffer |
| HS384 | HMAC | string | Buffer |
| HS512 | HMAC | string | Buffer |
| RS256 | RSA | Private key (sign), Public key (verify) |
| RS384 | RSA | Private key (sign), Public key (verify) |
| RS512 | RSA | Private key (sign), Public key (verify) |
| PS256 | RSA-PSS | Private key (sign), Public key (verify) |
| PS384 | RSA-PSS | Private key (sign), Public key (verify) |
| PS512 | RSA-PSS | Private key (sign), Public key (verify) |
| ES256 | ECDSA | Private key (sign), Public key (verify) |
| ES384 | ECDSA | Private key (sign), Public key (verify) |
| ES512 | ECDSA | Private key (sign), Public key (verify) |
| ES256K | ECDSA (secp256k1) | Private key (sign), Public key (verify) |
| EdDSA | Ed25519 | Private key (sign), Public key (verify) |
๐ก Keys must be in PEM format or as Node.js
KeyObject(e.g., fromcrypto.generateKeyPairSync).
๐ก๏ธ Security Features
โ
Correct ECDSA signatures (DER-encoded, not IEEE P1363)
โ
Full RSASSA-PSS and Ed25519 support
โ
Strict algorithm validation with whitelist (algorithms option) to prevent algorithm confusion
โ
Time claim validation (exp, nbf, iat) with clock skew tolerance
โ
Optional validation for:
โโข Issuer (iss)
โโข Subject (sub)
โโข Audience (aud)
โโข JWT ID (jti)
โ
Maximum token age enforcement (maxTokenAge)
โ
Type header enforcement (typ: 'JWT')
โ
Timing-safe signature comparison
โ
No unsafe defaults
๐ API Reference
Sync vs Promise API
| Operation | Sync Return | Promise Behavior |
|---|---|---|
sign() |
string |
Resolves to string |
decode() |
{ header, payload, signature } |
Resolves to same object |
verify() |
{ valid: true, ... } | { valid: false, error } |
Resolves on success Rejects with { reason, code } on failure |
sign(payload, secret, options?)
Sign a JWT.
payload:JWTPayloadobjectsecret: Key for signing (type depends on algorithm)options:alg: Algorithm (default:'HS256')kid: Key IDtyp: Token type (default:'JWT')
Returns: string (JWT)
verify(token, secret, options?)
Verify and validate a JWT.
token: JWT stringsecret: Key for verificationoptions:algorithms: Array of allowed algorithms (e.g.,['HS256', 'RS256'])issuer: Required value for theissclaimsubject: Required value for thesubclaimaudience: Required value(s) for theaudclaim (stringorstring[])jwtId: Required value for thejticlaimignoreExpiration: Skipexpcheck (default:false)clockSkew: Tolerance in seconds for time validation (default:0)maxTokenAge: Maximum allowed token age in seconds (fromiat)
Sync Usage:
const result = verify(token, secret, { issuer: 'https://example.com' });
if (result.valid) {
// success
} else {
// handle error: result.error
}Promise Usage:
try {
const { header, payload, signature } = await verify(token, secret, { issuer: 'https://example.com' });
// success
} catch (error) {
// handle error: error.reason, error.code
}Error Codes:
INVALID_TOKEN: Malformed token structureINVALID_ALGORITHM: Unsupported algorithmALGORITHM_NOT_ALLOWED: Algorithm not in allowed listINVALID_TYPE: InvalidtypheaderINVALID_SIGNATURE: Signature mismatchTOKEN_EXPIRED:expclaim exceededTOKEN_NOT_ACTIVE:nbfclaim not reachedTOKEN_FUTURE_ISSUED:iatclaim in futureTOKEN_TOO_OLD: Token age exceedsmaxTokenAgeMISSING_ISSUER/INVALID_ISSUERMISSING_SUBJECT/INVALID_SUBJECTMISSING_AUDIENCE/INVALID_AUDIENCEMISSING_JTI/INVALID_JTI
decode(token)
Decode a JWT without verification (use with caution!).
token: JWT string- Returns:
{ header, payload, signature } - Throws on malformed tokens (sync) / Rejects (promise)
๐งช Testing This library has 100% test coverage with Vitest:
npm test
npm run test:coverageTests include:
- All algorithms (HMAC, RSA, ECDSA, EdDSA, PSS)
- Time validation (
exp,nbf,iat,clockSkew,maxTokenAge) - Claim validation (
iss,sub,aud,jti) - Algorithm whitelisting
- Malformed token handling
- Signature verification (including timing-safe comparison)
- Custom claims
- Both sync and promise APIs
๐ฆ Exports This package provides two entrypoints:
| Import | Description |
|---|---|
@sourceregistry/node-jwt |
Sync API (default) |
@sourceregistry/node-jwt/promises |
Promise-based API |
Both include full TypeScript types and JSDoc.
๐ Contributing PRs welcome! Please:
- Add tests for new features
- Maintain 100% coverage
- Follow existing code style
Found a security issue? Report it responsibly.
๐ GitHub: github.com/SourceRegistry/node-jwt
๐ฆ npm: @sourceregistry/node-jwt