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

@nitrotool/jwt

v1.0.5

Published

Lightweight JWT utilities for Nuxt/Nitro/UnJS environments **with built-in h3 helpers**.

Readme

@nitrotool/jwt

Lightweight JWT utilities for Nuxt/Nitro/UnJS environments with built-in h3 helpers.

  • Built on @tsndr/cloudflare-worker-jwt
  • Helpers that read jwtSecret from your Nitro runtime config
  • Batteries included with h3 utilities to extract tokens from requests and enforce authentication

Learn more about JWT and how it works:

Installation

pnpm install @nitrotool/jwt
npm install @nitrotool/jwt

Required peer dependency:

  • h3 (this package expects h3 to be present)

Nuxt setup

export default defineNuxtConfig({
    modules: ['@nitrotool/jwt'],
    //You can also 
    jwt: {
        //default secret (only use this locally, and override it in prod)
        secret: 'some-random-secret-yes-it-is-not-very-secure',
        // Alternatively also available as NUXT_JWT_SECRET env var
    },
});

Usage with Nuxt 3/4

This is available all places where auto-imported can be used on the server-side.

type MyClaims = { tenantId: string };

const token = await encodeJwt<MyClaims>({tenantId: '123', sub: '123'});

// Later…
const isValid = await verifyJwt(token);
const payload = await decodeJwt<MyClaims>(token);


// or
export default defineEventHandler(async (event) => {
    const jwt = await requireJwt(event);
    // you now have access to a required JWT token via Authorization bearer header.
})

Importing

Import from the main entry or subpaths:

// Node-only helpers
import {encodeJwtRaw, verifyJwtRaw, decodeJwtRaw} from '@nitrotool/jwt/core';

// h3-only helpers
import {extractApiToken, requireApiToken} from '@nitrotool/jwt/h3';

Quick Start Nitro

1. Create plugin to load secret.

// plugins/0.jwt.ts
import { defineNitroPlugin, useRuntimeConfig } from 'nitropack/runtime';
import { configureJwtRuntime } from '@nitrotool/jwt';

export default defineNitroPlugin(() => {
    configureJwtRuntime(() => useRuntimeConfig() as any);
});

2. Basic usage

import {encodeJwt, verifyJwt, decodeJwt} from '@nitrotool/jwt';

type MyClaims = { tenantId: string };

const token = await encodeJwt<MyClaims>({tenantId: '123', sub: '123'});

// Later…
const isValid = await verifyJwt(token);
const payload = await decodeJwt<MyClaims>(token); // { sub: '123', tenantId: '123', exp: ... }

By default, non-Raw helpers read the secret from your runtime config:

  • useRuntimeConfig().jwtSecret

If you need to pass a secret explicitly, use the *Raw variants.

3. In a route handler

Extract API tokens and enforce authentication in request handlers:

Require a JWT token

import {defineEventHandler} from 'h3';
import {requireJwt} from '@nitrotool/jwt';

export default defineEventHandler(async (event) => {
    const decodedJwt = await requireJwt(event)
})

Extract a JWT token manually

import { defineEventHandler } from 'h3';
import { extractApiToken, requireApiToken, decodeJwt } from '@nitrotool/jwt';

export default defineEventHandler(async (event) => {
    // Try to read token (Authorization: Bearer <token> or ?<queryKey>=<token>)
    const token = extractApiToken(event, {queryKey: 'token'}); // queryKey defaults to 'token'

    // Or strictly require it (throws UnauthenticatedError if missing)
    const requiredToken = requireApiToken(event);

    // Optionally decode/verify
    const claims = await decodeJwt<{ userId: string }>(requiredToken);

    return { ok: true, userId: claims.userId };
});

Supported token locations:

  • Authorization header: Authorization: Bearer <token>
  • Query string: ?token=<token>

Configuration

When using non-Raw helpers, ensure a secret is available at runtime:

// nuxt.config.ts (Nuxt/Nitro runtime config)
export default defineNuxtConfig({
    runtimeConfig: {
        jwtSecret: 'some-random-secret-yes-it-is-not-very-secure',
    },
});

Examples

Sign with custom TTL:

import {encodeJwtRaw} from '@nitrotool/jwt';

const token = await encodeJwtRaw(
    {userId: '123', role: 'admin'},
    process.env.JWT_SECRET!,
    60 * 10 // 10 minutes
);

Decode without verifying signature (use only for non-sensitive scenarios):

import {decodeJwt} from '@nitrotool/jwt';

const payload = await decodeJwt<{ userId: string }>(token, {verify: false});

Verify with an explicit secret:

import {verifyJwtRaw} from '@nitrotool/jwt';

const ok = await verifyJwtRaw(token, process.env.JWT_SECRET!);

Errors

  • UnauthorizedError('Invalid JWT token.') is thrown when verification fails in decodeJwt / decodeJwtRaw.
  • UnauthenticatedError() is thrown by requireApiToken when no token is present.

Security Notes

  • Keep jwtSecret strong and private.
  • Prefer short TTLs and refresh flows.
  • Only set verify: false for non-sensitive, debug-like operations.
  • Rotate secrets periodically and invalidate old tokens if needed.

API Reference

All helpers are asynchronous.

JWT helpers

  • encodeJwtRaw<T>(payload, secret, ttl = 60): Promise<string>

    • Signs a token with the provided secret.
    • ttl is in seconds. Default: 60.
    • exp is set automagically from ttl.
  • encodeJwt<T>(payload, ttl = 60): Promise<string>

    • Same as encodeJwtRaw, but uses useRuntimeConfig().jwtSecret.
  • verifyJwtRaw(token, secret): Promise<boolean>

    • Verifies signature and expiry using the provided secret.
  • verifyJwt(token): Promise<boolean>

    • Same as verifyJwtRaw, but uses useRuntimeConfig().jwtSecret.
  • decodeJwtRaw<T>(token, secret, { verify = true } = {}): Promise<T & Partial<JwtPayload>>

    • Decodes the token. When verify is true, verifies signature and expiry.
    • Throws UnauthorizedError('Invalid JWT token.') if verification fails.
    • Throws if verify is true but secret is empty.
  • decodeJwt<T>(token, { verify = true } = {}): Promise<T & Partial<JwtPayload>>

    • Same as decodeJwtRaw, but uses useRuntimeConfig().jwtSecret.
    • Throws UnauthorizedError('Invalid JWT token.') if verification fails.

Types:

  • ExtendableJwtPayload<T> lets you define custom claims merged with standard JWT claims.

h3 helpers (required)

  • extractBearerToken(event): string | undefined

    • Reads Authorization header and returns the token without Bearer .
  • extractQueryToken(event, key = 'token'): string | undefined

    • Reads token from the query string.
  • extractApiToken(event): string | undefined

    • Returns the first non-empty token found by extractBearerToken or extractQueryToken.
  • requireApiToken(event): string

    • Same as extractApiToken, but throws UnauthenticatedError if missing.

License

MIT