node-jwt
    Preparing search index...

    node-jwt

    πŸ” @sourceregistry/node-jwt

    npm version License CI Codecov

    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), automatic algorithm detection, JWK/JWKS, 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
    • TypeScript-first with full JSDoc
    • Zero external dependencies
    • 100% test coverage (TryingπŸ˜‰)
    • Dual API: Sync and Promise-based
    • Automatic algorithm detection based on key type
    • Full JWK/JWKS support (import/export, toPublicJWK, x5c/x5t, RFC 7638 thumbprints, kid-based key selection)

    npm install @sourceregistry/node-jwt
    

    Requires Node.js β‰₯ 16


    import { sign, verify, decode } from '@sourceregistry/node-jwt';

    // Sign (algorithm auto-detected)
    const token = sign(
    { sub: '1234567890', name: 'John Doe', iat: Math.floor(Date.now() / 1000) },
    'your-secret-key'
    );

    // 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);
    import { sign, verify, decode } from '@sourceregistry/node-jwt/promises';

    // Sign (algorithm auto-detected)
    const token = await sign(
    { sub: '1234567890', name: 'John Doe', iat: Math.floor(Date.now() / 1000) },
    'your-secret-key'
    );

    // Verify
    try {
    const { payload } = 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);

    When options.alg is omitted, the library automatically selects the correct JWT algorithm based on the signing key.

    Key Type Detection Logic Selected Algorithm
    Symmetric (string / Buffer) Default HMAC HS256
    RSA private key PKCS#1 v1.5 RS256
    RSA-PSS private key Hash algorithm in key PS256 / PS384 / PS512
    EC P-256 (prime256v1) Curve name ES256
    EC P-384 (secp384r1) Curve name ES384
    EC P-521 (secp521r1) Curve name ES512
    EC secp256k1 Curve name ES256K
    Ed25519 Key type EdDSA

    πŸ’‘ Node.js exposes OpenSSL curve names (prime256v1, secp384r1, etc.). These are automatically normalized to JOSE algorithms.

    Autodetection fails for unsupported keys:

    • Unsupported EC curve
    • Unsupported RSA-PSS hash algorithm (e.g. sha1)
    • Unsupported asymmetric key type (e.g. DSA)

    Algorithm Type Secret Type
    HS256 / HS384 / HS512 HMAC string | Buffer
    RS256 / RS384 / RS512 RSA Private / Public key
    PS256 / PS384 / PS512 RSA-PSS Private / Public key
    ES256 / ES384 / ES512 ECDSA Private / Public key
    ES256K ECDSA (secp256k1) Private / Public key
    EdDSA Ed25519 Private / Public key

    Keys may be PEM, DER, JWK, or Node.js KeyObject.


    • Import/export JWK: importJWK(), exportJWK()
    • Convert to public-only JWK: toPublicJWK()
    • Compute RFC 7638 thumbprint: getJWKThumbprint()
    • Support x5c/x5t (X.509 cert chain + SHA-1 thumbprint)
    • Normalize JWKS with auto-generated kid and x5t
    • Resolve keys from JWKS by kid for verification
    import { JWKS, JWK } from '@sourceregistry/node-jwt';

    const keyPair = generateKeyPairSync('rsa', { modulusLength: 2048 });
    const jwk = JWK.toPublic(keyPair.publicKey);
    const jwks = JWKS.normalize({ keys: [jwk] });

    // Retrieve key by kid
    const keyObject = JWKS.toKeyObject(jwks, jwk.kid);

    • βœ… Safe algorithm autodetection
    • βœ… Strict algorithm whitelisting (algorithms option)
    • βœ… Full RSASSA-PSS and Ed25519 support
    • βœ… Time claim validation (exp, nbf, iat) with clock skew
    • βœ… Claim validation (iss, sub, aud, jti)
    • βœ… Maximum token age enforcement
    • βœ… Timing-safe signature comparison
    • βœ… No insecure defaults

    For ECDSA algorithms (ES256, ES384, ES512, ES256K) there are two common signature encodings:

    • DER (ASN.1) β€” what Node.js produces by default
    • JOSE (r || s raw signature) β€” required by the JWT/JWS spec and used by systems like VAPID/Web Push (WNS)

    By default, this library outputs DER signatures for ES* algorithms to match Node.js/OpenSSL defaults.

    To generate spec-compliant JOSE ECDSA signatures, set:

    • signatureFormat: "jose" in sign()
    import { sign, verify } from "@sourceregistry/node-jwt";

    const token = sign(
    { sub: "123", iat: Math.floor(Date.now() / 1000) },
    ecPrivateKey,
    { alg: "ES256", signatureFormat: "jose" }
    );

    // Verify JOSE-signed token
    const result = verify(token, ecPublicKey, { signatureFormat: "jose" });

    If enabled in your version, verify() can also validate JOSE ECDSA signatures without specifying signatureFormat (it will try DER first, then JOSE). If you want strict behavior, pass signatureFormat: "der" or signatureFormat: "jose" explicitly.

    πŸ’‘ For VAPID/Web Push (e.g. Windows WNS endpoints), you typically need ES256 with signatureFormat: "jose".

    • alg (optional) β€” If omitted, algorithm is auto-detected
    • kid β€” Key ID
    • typ β€” Token type (default: "JWT")

    Includes algorithm whitelist protection and full claim validation.

    Error Codes include:

    • INVALID_TOKEN
    • INVALID_ALGORITHM
    • ALGORITHM_NOT_ALLOWED
    • INVALID_SIGNATURE
    • TOKEN_EXPIRED
    • TOKEN_NOT_ACTIVE
    • TOKEN_TOO_OLD
    • MISSING_* / INVALID_*

    Decode a JWT without verification (unsafe).


    • 100% branch coverage
    • All algorithms + autodetection paths
    • All failure modes
    • Sync + Promise APIs
    • Full JWK/JWKS coverage (import/export, x5c/x5t, thumbprint, kid selection)
    npm test
    npm run test:coverage

    Import Description
    @sourceregistry/node-jwt Sync API
    @sourceregistry/node-jwt/promises Promise API

    PRs welcome! Please add tests and maintain full coverage.

    πŸ” Security issues? Report responsibly: a.p.a.slaa@projectsource.nl

    πŸ”— GitHub: https://github.com/SourceRegistry/node-jwt πŸ“¦ npm: https://www.npmjs.com/package/@sourceregistry/node-jwt