Skip to content

JWT Debugger — JavaScript source

Decode a JSON Web Token and inspect its header and payload as pretty JSON, with exp/iat claim awareness and an expiry badge. Runs entirely in your browser.

This is the JavaScript implementation — the same logic the interactive tool runs, in a shareable, citable form.

/**
 * JWT base64url decoding helper - JavaScript port.
 *
 * Language: JavaScript (ES2020+, runs in browsers / Node 16+ / Cloudflare Workers)
 * CosmoDev polyglot showcase port of the `jwt` tool.
 * Ported from src/lib/jwt.ts.
 *
 * Display source - part of CosmoDev's polyglot tool pages
 * (dev.cosmolabs.org).
 *
 * Decode-only - JWT signatures are verified server-side, never in the page.
 * The single exported helper turns a base64url string (the alphabet every JWT
 * header/payload segment is encoded with) back into text. It is the direct,
 * type-stripped twin of the canonical TypeScript implementation.
 */

/**
 * Decode a base64url string to text.
 *
 * JWT segments use RFC 4648's URL-safe base64 alphabet: `-` and `_` stand in
 * for `+` and `/`, and the trailing `=` padding is usually omitted. The Web
 * `atob` decoder only understands the standard alphabet, so we:
 *
 *   1. map the URL-safe characters back to `+` / `/`,
 *   2. re-append `=` until the length is a multiple of 4 (base64 always works
 *      in 4-char blocks), then
 *   3. decode.
 *
 * `atob` returns a "binary string" - one JS character per decoded byte, where
 * the byte value is the character code. That byte-faithful mapping round-trips
 * the full 0x00-0xFF range (it is effectively Latin-1), which is exactly what
 * the JWT debugger's test vectors expect.
 *
 * Throws on input that is not valid base64 (the error propagates from `atob`).
 *
 * @param {string} str - base64url-encoded text (a JWT header or payload segment)
 * @returns {string} the decoded binary string
 */
export function b64urlDecode(str) {
  // 1. URL-safe alphabet -> standard base64 alphabet.
  let s = str.replace(/-/g, '+').replace(/_/g, '/');
  // 2. Restore any stripped '=' padding so the length is a multiple of 4.
  while (s.length % 4) s += '=';
  // 3. Standard base64 -> binary string (byte value === character code).
  return atob(s);
}

Also available in 13 other languages

Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →