jwt-decode

A lightweight TypeScript library for decoding JSON Web Token payloads and headers in the browser and Node.js.

Library
npm
v4.0.0
3,401 stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
62 /100 Good
Development Activity 44
Maintenance 20
Community 84
Maturity 60
Momentum 40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
70 /100 Good
Architecture 75
Code Quality 80
Innovation 78
Learning Curve 45

jwt-decode is a zero-runtime-dependency library for decoding JSON Web Tokens (JWTs) in browser and Node.js environments. It exposes a single function, jwtDecode, that splits a JWT into its base64url-encoded segments and returns the decoded JSON payload (or header) as a plain object — it does not verify the token’s signature. Maintained by Auth0, it ships dual ESM and CommonJS builds plus a standalone browser script-tag entry point, and is one of the most widely depended-on packages in the JavaScript JWT ecosystem at roughly 18 million weekly downloads.

The library specifically handles the tricky parts of base64url decoding: non-standard padding lengths, UTF-8/unicode payload characters, and malformed input. It throws a typed InvalidTokenError with a descriptive message distinguishing between a non-string token, a missing segment, invalid base64, and invalid JSON, so callers can branch on failure without string-matching generic errors. Because it deliberately does not validate signatures, the README recommends pairing it with a server-side verification library (express-jwt, koa-jwt, or a framework’s built-in JWT bearer middleware) whenever a token’s authenticity must be trusted rather than just its claims read.

What You Get

  • A single jwtDecode() function that returns the parsed JWT payload or header as a typed object.
  • TypeScript types for JwtHeader and JwtPayload, extensible with your own custom claim shapes via generics.
  • A typed InvalidTokenError class with specific messages for missing parts, invalid base64, and invalid JSON.
  • Dual ESM/CommonJS build output plus a browser-ready ES module file for direct <script type="module"> use.

Common Use Cases

  • Reading claims client-side - Decoding an access or ID token in a single-page app to read claims like exp or sub without a server round-trip.
  • Checking token expiry - Comparing the decoded exp/iat timestamps in the browser to decide whether a session token needs refreshing before an API call.
  • Inspecting a JWT header for kid - Passing { header: true } to retrieve the header segment and select the correct signing key elsewhere in a verification flow.
  • Non-browser environments - Combined with an atob polyfill such as core-js/stable/atob, decoding tokens in runtimes (e.g. older React Native) that lack a native atob global.

Under The Hood

Architecture

The library is intentionally a single module (lib/index.ts): one exported jwtDecode function, two private helpers (b64DecodeUnicode and base64UrlDecode) for the base64url-to-unicode transform, and an InvalidTokenError class. There is no internal layering, dependency injection, or I/O — jwtDecode is a pure synchronous string-to-object transform, so the entire “architecture” is a single, narrow surface. The build step compiles this one file twice, once each for tsconfig.cjs.json and tsconfig.esm.json, with a prebuild script stamping a package.json into the CJS output directory so Node resolves it as CommonJS. Given the package’s scale (tens of millions of weekly downloads), any change to the jwtDecode signature or error messages would ripple across an enormous number of consumers instantly, so the minimalism looks deliberate rather than accidental.

Tech Stack

Written in TypeScript with zero runtime dependencies (it relies only on the global atob), compiled with the native tsc compiler (no bundler like esbuild/tsup), and tested with Jest across both a node and a jsdom test environment to exercise browser and non-browser code paths. Linting uses ESLint 9’s flat config with typescript-eslint, formatting is enforced with Prettier and lint-staged/Husky pre-commit hooks, and package correctness is checked with publint. CI runs a Node 18/20 build matrix on GitHub Actions, with Snyk and Semgrep scanning for dependency and code-level security issues, and releases are automated via a dedicated npm-release workflow keyed off release branches.

Code Quality

The single test file exercises the default payload decode, header decoding via { header: true }, UTF-8 and binary payload edge cases, both single- and double-character base64 padding, and every InvalidTokenError branch (non-string input, missing token part, invalid base64, invalid JSON) — solid coverage for a small, focused surface area, though there’s no dedicated test asserting the compiled CJS/ESM build artifacts themselves. TypeScript strict typing is used throughout, errors are raised as a distinguishable typed class rather than generic Error throws, and every PR runs lint, format-check, and both test suites in CI before merge.

API Design The public API is a single function with a sensible default (jwtDecode(token) decodes the payload; { header: true } opts into decoding the header instead), and overloaded TypeScript signatures give strong return-type inference based on that option without requiring a manual type assertion. There’s no setup, configuration object, or class instantiation required — install and call. The main friction points are the reliance on a global atob (requiring a polyfill in environments like older React Native) and the fact that “decode” deliberately does not mean “verify,” which the README calls out prominently since it is a common source of confusion for developers who assume decoding implies the token is trustworthy.

Used by 25 apps in this directory

TypeScript
73%
Apache 2.0

Jitsi Meet

Collaboration · Team Chat · Video Conferencing

30,130

Open-source, end-to-end encrypted video conferencing you can self-host or embed into any web or mobile app.

View details
96
Repo Health
85
Technical
67
Dependency
Built with
TypeScript 73%
Lua 11%
JavaScript 10%
Updated 1 weeks ago
Python
55%
MIT

LibrePhotos

File Storage

8,111

Self-hosted photo library with AI-powered face recognition, semantic search, and automatic event albums — no cloud required.

View details
84
Repo Health
78
Technical
66
Dependency
Built with
Python 55%
TypeScript 43%
Updated 1 weeks ago
Python
84%
MIT

LiteLLM

AI Development · Developer Tools

61,933

Open source AI gateway and Python SDK that gives you one OpenAI-compatible interface to call 100+ LLM providers, with built-in routing, cost tracking, guardrails, and virtual keys.

View details
93
Repo Health
81
Technical
69
Dependency
Built with
Python 84%
TypeScript 11%
Updated 1 weeks ago
Go
81%
GPL 3.0

Navidrome

File Storage · Music Audio

24,331

Run your own personal Spotify — stream your entire music collection from any device, anywhere, forever.

View details
91
Repo Health
81
Technical
66
Dependency
Built with
Go 81%
JavaScript 15%
Updated 1 weeks ago
TypeScript
65%
Other

NocoDB

Databases · Low Code Platforms · No Code Platforms

65,340

Turn any SQL database into a collaborative no-code spreadsheet with automatic REST APIs and real-time views.

View details
91
Repo Health
77
Technical
63
Dependency
Built with
TypeScript 65%
Vue 30%
Updated 1 weeks ago
TypeScript
98%
Other

Novu

Developer Tools

40,195

Open-source communication infrastructure that connects your products and AI agents to every channel your users live on — Inbox, Email, SMS, Push, Chat, and more.

View details
93
Repo Health
80
Technical
64
Dependency
Built with
TypeScript 98%
Updated 1 weeks ago
TypeScript
96%
Apache 2.0

OneUptime

Monitoring

7,751

The complete open-source observability platform that replaces PagerDuty, Datadog, Sentry, and StatusPage with a single self-hostable system.

View details
91
Repo Health
81
Technical
65
Dependency
Built with
TypeScript 96%
Updated 1 weeks ago
JavaScript
90%
Other

OpenSign

Digital Signiture

7,163

Self-host a full-featured DocuSign alternative with unlimited e-signatures, multi-signer workflows, and cryptographic PDF signing.

View details
83
Repo Health
61
Technical
69
Dependency
Built with
JavaScript 90%
Updated 1 weeks ago
TypeScript
96%
MIT

Payload CMS

Blogging · CMS · Developer Tools

45,458

The open-source, Next.js-native headless CMS that lives inside your /app folder and gives you a full TypeScript backend instantly.

View details
92
Repo Health
88
Technical
65
Dependency
Built with
TypeScript 96%
Updated 1 weeks ago

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers