npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@bepalo/jwt

v2.0.9

Published

A secure and tested json-web-token class-based utility library for generating keys, signing, verifying, and decoding JWT payloads for use with your high-security demanding projects.

Downloads

30

Readme

🏆 @bepalo/jwt

npm version jsr github GitHub Repo stars

license Node.js Bun Deno CI Tests Vitest

A secure and tested json-web-token class-based utility library for generating keys, signing, verifying, and decoding JWT payloads for use with your high-security demanding projects.

Table of Contents

✨ Features

  • 🎯 JWT sign and verify with HMAC, ECDSA, RSA, RSA-PSS algorithms.
  • 🗝️ Easy key generation support.
  • ♻️ Synchronous by default, with asynchronous alternatives.
  • ⌚ Time helper functions from @bepalo/time.
  • 📄 Written in modern TypeScript.
  • 📢 Available for both ESM and CommonJS.
  • 📢 Works with Node, Bun, and Deno.
  • 📢 Built on the crypto API.

🚀 Get Started

📥 Installation

Node.js / Bun (npm / pnpm / yarn)

bun add @bepalo/jwt
# or
pnpm add @bepalo/jwt
# or
npm install @bepalo/jwt
# or
yarn add @bepalo/jwt

Deno

Import directly using the URL:

import { JWT } from "npm:@bepalo/jwt";
// or
import { JWT } from "jsr:@bepalo/jwt";

🚀 Quick Start

Simple Symmetric HMAC:

import { JWT } from "@bepalo/jwt";

// 1. Generate a key
const secret = JWT.genHmac("HS256");

// 2. Store the generated key somewhere safe like in a .env file
console.log(secret);

// 3. Load that key from where it was stored
const signKey = process.env.SECRET;
const verifyKey = process.env.SECRET;

// 4. Create a JWT instance for signing
const jwtSign = JWT.createSymmetric(signKey, "HS256");

// 5. Sign a payload
const token = jwtSign.signSync({ 
  userId: 123, 
  role: "admin", 
  jti: "tid-1234",
  iat: JWT.now(), 
  // exp: JWT.on("2026"),
  // nbf: JWT.after(5).Minutes,
  // ...
});

// 6. Create another JWT instance for verifying. *optional*
const jwtVerify = JWT.createSymmetric(verifyKey, "HS256");

// 7. Verify and decode the token
const { valid, payload, error } = jwtVerify.verifySync(token, {
  jti: "tid-1234",
  nbfLeeway: JWT.for(5).Seconds
});

// 8. Deal with errors or use the payload
console.log(valid);    // true
console.log(payload);  // { userId: 123, role: "admin", ... }
console.log(error);    // undefined

Generic:

import { JWT } from "@bepalo/jwt";

// 1. Generate a key
const key = JWT.genKey("ES256");

// 2. Store the generated key somewhere safe like in a .env file
const { alg, publicKey, privateKey } = key;
console.log(JSON.stringify({ alg, publicKey }));
console.log(JSON.stringify({ alg, privateKey }));

// 3. Load that key from where it was stored
const signKey = JSON.parse(process.env.PRIVATE_KEY ?? "null");
const verifyKey = JSON.parse(process.env.PUBLIC_KEY ?? "null");

// 4. Create a JWT instance for signing
const jwtSign = JWT.create(signKey);

// 5. Sign a payload
const token = jwtSign.signSync({ 
  userId: 123, 
  role: "admin", 
  jti: "tid-1234",
  iat: JWT.now(), 
  // exp: JWT.on("2026"),
  // nbf: JWT.after(5).Minutes,
  // ...
});

// 6. Create a JWT instance for verifying
const jwtVerify = JWT.create(verifyKey);

// 7. Verify and decode the token
const { valid, payload, error } = jwtVerify.verifySync(token, {
  jti: "tid-1234",
  nbfLeeway: JWT.for(5).Seconds
});

// 8. Deal with errors or use the payload
console.log(valid);    // true
console.log(payload);  // { userId: 123, role: "admin", ... }
console.log(error);    // undefined

✅ Usage

🔑 Key Creation

import { JWT } from "@bepalo/jwt";

// 📢 Symmetric HMAC key generation. returns string
const secret = JWT.genHmac("HS256");

// 📢 Generic way of generating any key. returns JwtKey
const key = JWT.genKey("none");
const key = JWT.genKey("HS512"); 
const key = JWT.genKey("ES384"); 
const key = JWT.genKey("RS256"); 
const key = JWT.genKey("PS256"); 

🏗️ JWT Instance Creation

import { JWT } from "@bepalo/jwt";

type Payload = { userId: number, role: "admin" | "user" };

const secret = JWT.genHmac("HS256");
// 📢 Symmetric only way of creating a JWT instance.
const jwt = JWT.createSymmetric<Payload>(secret, "HS256");

const key = JWT.genKey("ES256"); 
// 📢 Generic way of creating a JWT instance
const jwt = JWT.create<Payload>(key);

✍️ Signing

Synchronous:

import { JWT } from "@bepalo/jwt";

type Payload = { userId: number, role: "admin" | "user" };

const key = JWT.genKey("HS256"); 
const jwt = JWT.create<Payload>(key);

// 📢 Sign synchronously
const token = jwt.signSync({ userId: 123, role: "admin", iat: JWT.now() });

Asynchronous:

import { JWT } from "@bepalo/jwt";

type Payload = { userId: number, role: "admin" | "user" };

const key = JWT.genKey("HS256"); 
const jwt = JWT.create<Payload>(key);

// 📢 Sign asynchronously
const token = await jwt.sign({ userId: 123, role: "admin", iat: JWT.now() });

🔎 Verification

Synchronous:

import { JWT } from "@bepalo/jwt";

type Payload = { userId: number, role: "admin" | "user" };

const key = JWT.genKey("HS256"); 
const jwt = JWT.create<Payload>(key);

const token = jwt.signSync({ userId: 123, role: "admin", iat: JWT.now() });

// 📢 Verify synchronously
const { valid, payload, error } = jwt.verifySync(token);

// 📢 Verify signature synchronously
const { valid, error } = jwt.verifySignatureSync(token);

Asynchronous:

import { JWT } from "@bepalo/jwt";

type Payload = { userId: number, role: "admin" | "user" };

const key = JWT.genKey("HS256"); 
const jwt = JWT.create<Payload>(key);

const token = await jwt.sign({ userId: 123, role: "admin", iat: JWT.now() });

// 📢 Verify asynchronously
const payload = await jwt.verify(token);

// 📢 Verify signature asynchronously
const valid = await jwt.verifySignature(token);

⚙️ Verify Options

import { JWT } from "@bepalo/jwt";

type Payload = { userId: number, role: "admin" | "user" };

const key = JWT.genKey("HS256"); 
const jwt = JWT.create<Payload>(key);

const token = await jwt.sign({
  userId: 123, 
  role: "admin", 
  iat: JWT.now(),
  nbf: JWT.after(5).Minutes,
  exp: JWT.on("2026"),
  jti: "jti-1234",
  iss: "auth-server",
  sub: "session",
  aud: ["auth-client-a", "auth-client-b"],
});

const payload = await jwt.verify(token, {
  strict: false, // default: true
  iss: "auth-server",
  aud: "auth-client-a", // or ["auth-client-a", "auth-client-c"]
  sub: "session",
  jti: "jti-1234",
  exp: true, // default: true
  nbf: false, // default: true
  expLeeway: JWT.for(5).Seconds,
  nbfLeeway: JWT.for(5).Seconds,
});

const valid = await jwt.verifySignature(token, { strict: false });

📚 Quick Docs

All errors thrown or returned by this library are instances of JwtError with a descriptive message and a smart error code.

// Using Time and RelativeTime for fluent time expression feature.
import type { Time, RelativeTime } from "@bepalo/time";

/**
 * JWT class providing utility function and methods to generate keys, and sign, verify and decode tokens.
 */
class JWT<Payload> {

  // Get the current time in seconds.
  static now(): number;
  
  // Get the given date-time in seconds.
  static on(date): number;

  // Fluently define absolute time in seconds. 
  // eg. `JWT.for(1).Day`
  static for(): Time;
  
  // Fluently define the relative time in seconds. 
  // eg. `JWT.in(10).Hours`
  static in(): RelativeTime;
  
  // Fluently define the relative time in seconds. 
  // eg. `JWT.after(5).Minutes`
  static after(): RelativeTime;

  // Fluently define the relative time in seconds. 
  // eg. `JWT.before(1).Week`
  static before(): RelativeTime;


  // Generate a random key for HMAC
  static genHmac(alg): string;

  // Generate a generic jwt key based on algorithm and optional parameters
  static genKey(alg, options?): Key;

  // Create a JWT instance using a symmetric algorithm.
  static createSymmetric<Payload>(secret, alg): JWT<Payload>;

  // Create a JWT instance using an asymmetric JwtKey.
  static createAsymmetric<Payload>(key): JWT<Payload>;

  // Create a JWT instance using a generic JwtKey.
  static create<Payload>(key): JWT<Payload>;


  // Synchronously sign a payload and return a JWT token string.
  signSync(payload): string

  // Asynchronously sign a payload and return a JWT token string.
  sign(payload): Promise<string>


  // Synchronously verify only the token and the signature (no payload or claims are checked).
  verifySignatureSync(token, verifyJwtStrict?): JwtResult<Payload> 

  // Asynchronously verify only the signature of the token (no claims checked).
  verifySignature(token, verifyJwtStrict?): Promise<boolean>;


  // Synchronously verify a token, signature, payload and claims.
  verifySync(token, verifyJwt?): JwtResult<Payload>;

  // Asynchronously verify a token, signature, payload and claims.
  verify(token, verifyJwt?): Promise<JwtPayload<Payload>>;

}
/**
 * Error class for use with this JWT library
 */
class JwtError extends Error {
  code: JwtErrorCode;
}
/**
 * JWT verify result type
 */
type JwtResult<Payload> = {
  valid: boolean;
  payload?: JwtPayload<Payload>;
  error?: JwtError;
};
/**
 * JWT Key type
 */
type JwtKey = { 
  alg: JwtAlgorithm, 
  publicKey: string; 
  privateKey: string 
};
/**
 * Optional parameters for verifying a JWT.
 */
type JwtVerifyOptions = {
  // Decoded algorithm must match the stored algorithm. default: true
  strict?: boolean;
  // Expected issuer
  iss?: string;
  // Expected audience/s
  aud?: string | string[];
  // Expected subject
  sub?: string;
  // Expected token id
  jti?: string;
  // Enable/disable expiration time check. default: true
  exp?: boolean;
  // Enable/disable not-before time check. default: true
  nbf?: boolean;
  // Leeway in seconds for expiration time
  expLeeway?: number;
  // Leeway in seconds for not-before time
  nbfLeeway?: number;
};
// Supported symmetric algorithms
type JwtSymmetricAlgorithm = "HS256" | "HS384" | "HS512";

// Supported asymmetric algorithms
type JwtAsymmetricAlgorithm =
  | "RS256"
  | "RS384"
  | "RS512"
  | "ES256"
  | "ES384"
  | "ES512"
  | "PS256"
  | "PS384"
  | "PS512";

// All supported JWT algorithms
type JwtAlgorithm =
  | JwtSymmetricAlgorithm
  | JwtAsymmetricAlgorithm
  | "none";
/**
 * Smart Error codes for use with this JWT library
 */
enum JwtErrorCode {
  internalError = 0,

  invalid = 100,

  tokenInvalid = 110,
  tokenTypeInvalid = 111,

  tokenHeaderInvalid = 120,

  algorithmInvalid = 130,
  algorithmMismatch = 131,

  signatureInvalid = 140,
  signatureMismatch = 141,

  payloadInvalid = 150,

  // for use with your custom validation errors
  claimInvalid = 200,
  claimMismatch = 201,

  jti = 210,
  jtiMismatch = 210,
  jtId = 210,
  jtIdMismatch = 210,

  iss = 220,
  issMismatch = 220,
  issuer = 220,
  issuerMismatch = 220,

  sub = 230,
  subMismatch = 230,
  subjet = 230,
  subjectMismatch = 230,

  aud = 240,
  audMismatch = 240,
  audience = 240,
  audienceMismatch = 240,

  exp = 250,
  expired = 250,

  nbf = 260,
  notValidYet = 260,
  notYetValid = 260,
  notBefore = 260,

  keyInvalid = 300,
  privateKeyInvalid = 301,
  publicKeyInvalid = 302,
};

🛡️ Supported Algorithms

📕 The ES512(P-521) algorithm is less common and might not be supported on the runtime of your preference. But you can use ES256 or ES384, or switch to a runtime that supports it.

  • HS256: Most common and secure.
  • HS384: Slightly stronger but less common.
  • HS512: High-security option for robust applications.
  • ES256: Recommended alternative to RSA.
  • ES384: Stronger cryptographic security.
  • ES512: Best for ultra-secure environments. NOTE: May not be supported/implemented in all runtimes.
  • RS256: Widely used.
  • RS384: Stronger but heavier.
  • RS512: Computationally expensive but highly secure.
  • PS256: RSA-PSS variant with SHA-256.
  • PS384: RSA-PSS variant with SHA-384.
  • PS512: RSA-PSS variant with SHA-512.

For more details, see RFC 7519 and IANA JWT Algorithms.

🔗 Links

@bepalo/time

npm jsr github

🕊️ Thanks, Stay Safe and Enjoy

If you like this library and want to support then please give a star on GitHub GitHub Repo stars

💖 Be a Sponsor

Fund me so I can give more attention to the products and services you liked.