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:
๐ฆ Installation
npm install @sourceregistry/node-jwt
Requires Node.js โฅ 16
๐ Quick Start
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);
/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
| 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: JWTPayload objectsecret: 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 the iss claimsubject: Required value for the sub claimaudience: Required value(s) for the aud claim (string or string[])jwtId: Required value for the jti claimignoreExpiration: Skip exp check (default: false)clockSkew: Tolerance in seconds for time validation (default: 0)maxTokenAge: Maximum allowed token age in seconds (from iat)const result = verify(token, secret, { issuer: 'https://example.com' });
if (result.valid) {
// success
} else {
// handle error: result.error
}
try {
const { header, payload, signature } = await verify(token, secret, { issuer: 'https://example.com' });
// success
} catch (error) {
// handle error: error.reason, error.code
}
INVALID_TOKEN: Malformed token structureINVALID_ALGORITHM: Unsupported algorithmALGORITHM_NOT_ALLOWED: Algorithm not in allowed listINVALID_TYPE: Invalid typ headerINVALID_SIGNATURE: Signature mismatchTOKEN_EXPIRED: exp claim exceededTOKEN_NOT_ACTIVE: nbf claim not reachedTOKEN_FUTURE_ISSUED: iat claim in futureTOKEN_TOO_OLD: Token age exceeds maxTokenAgeMISSING_ISSUER / INVALID_ISSUERMISSING_SUBJECT / INVALID_SUBJECTMISSING_AUDIENCE / INVALID_AUDIENCEMISSING_JTI / INVALID_JTIdecode(token)Decode a JWT without verification (use with caution!).
token: JWT string{ header, payload, signature }๐งช Testing This library has 100% test coverage with Vitest:
npm test
npm run test:coverage
Tests include:
exp, nbf, iat, clockSkew, maxTokenAge)iss, sub, aud, jti)๐ฆ 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:
Found a security issue? Report it responsibly.
๐ GitHub: github.com/SourceRegistry/node-jwt
๐ฆ npm: @sourceregistry/node-jwt