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

twj

v0.1.0

Published

A minimal suite of functions for handling JWT tokens. Cryptographic signing, cryptographic verification, and JWT standard claims validation.

Readme

TWJ

pipeline status coverage report

Why?

Because jose -- the only other viable choice -- is unstable, whimsically rewritten, poorly organized, and bloated.

Design Goals

TWJ aims to be production-grade software, suitable for real-world commercial workloads of millions of users authenticating with JWT tokens.

  • Backwards compatibility / stable interface
  • Deterministic execution
  • High reliability
  • Fast performance
  • Laser-focused on real-world usage
  • Zero dependencies
  • Lightweight implementation
  • Readable code, suitable for learning and self-education
  • Secure and trustworthy

Installing

Install twj using your favorite npm package manager.

$ npm install --save twj

Usage

createSigner() -- Signing a set of JWT claims

Common JWT claims include sub, iss, iat, exp, aud. You can pass any claims to the signer you want. There is no enforcement or validation of claims while signing.

First off, here is how to import the module for creating a signer:

import { createSigner } from 'twj';

Once you have createSigner(), you can use it to create a sign() function:

const sign = createSigner({
  key: {/* ...your private key in JWK format */}
});

Recommended: Include a "kid" property in your private key. If present, this property will be included in the token header, enabling dynamic key lookup during token verification.

Now that you have a sign() function, you can begin using it to sign JWT claims:

const token = await sign({/* ...any JWT claims you want signed...*/});

The result is a signed JWT token string with the given claims.

createVerifier() -- Verifying a signed JWT token and extracting its claims

import { createVerifier } from 'twj';

Once you have createVerifier(), you can use it to create a verify() function:

const verify = createVerifier({
  key: {
    /* ...a public key, in JWK format, trusted for signing legitimate tokens */
  }
});

Alternatively, key can be an asynchronous function that, given the deserialized token header and payload objects, resolves to the corresponding public key, in JWK format, to use for verifying that token (or rejects if no trusted key can be found):

const verify = createVerifier({
  key: async ({ header, payload }) => {
    // Find a trusted public key to use to verify this token.
    // If no trusted public key can be found, then reject/throw.
    // Else, resolve with the trusted public key as a JWK object.
  }
});

Finally, once you have a verify() function, you can begin using it to verify tokens:

const claims = await verify(token);

Important: The verify() function DOES NOT enforce JWT claims. It just ensures the token is authentic and signed by a trusted issuer. You probably still want to use validate() as well to enforce claims of interest.

createValidator() -- Validating JWT claims

JWT claim validation occurs after verifying the token is signed by a trusted issuer. Therefore, the claims in the token are known to have been true at some point in the past. Validation is the phase where these claims are examined to determine if they are still true, and if they are true for this context.

Some examples of validation rules include:

  • Ensuring that if the token claims to expire, that it is not currently expired.

  • Ensuring that if the token claims when it was issued, that it was not issued in the future.

  • Ensuring that if the token claims an audience, that we identify with that audience.

  • Ensuring that if the token claims an issuer, that we trust that issuer.

Let's import the createValidator() module:

import { createValidator } from 'twj';

Now, let's initialize it with how we'd like to validate our claims:

const validate = createValidator({
  audiences: [
    'https://example.com'
  ]
});

In this example, we're configuring our validator to reject any token whose aud claim is not 'https://example.com'. Any exp and/or iat claims, if present, will be validated using the default system clock and default clock drift tolerance. The iss claim, if present, will be ignored, because there are no allow-listed issuers in the configuration object.

  • options.audiences (string[]) - A set of values to accept for a token's aud claim.

  • options.clockToleranceSeconds (Number) - How many seconds to tolerate during temporal validation on exp and iat claims. Defaults to 30.

  • options.currentTimeSeconds (function():Number) - A function that returns the current time in seconds as a whole number relative to Unix epoch. Used for temporal validation on exp and iat claims. Defaults to using the system clock.

  • options.issuers (string[]) - A set of values to accept for a token's iss claim.