JWT Decoder

Token never leaves your browser

Decode and inspect JSON Web Tokens. View header, payload, claims, and expiry status instantly. Client-side only — your token never leaves the browser.

JWT Token

Runs entirely in your browser — nothing is uploaded
Runs entirely in your browser. No uploads. Your files stay private.

What Is a JWT Decoder?

A JSON Web Token (JWT, RFC 7519) is a compact, URL-safe credential made of three Base64url-encoded segments separated by dots: header, payload, and signature. The header declares the signing algorithm (alg) and token type (typ); the payload carries the claims; the signature binds the first two parts to a secret or private key so a server can detect tampering.
This decoder splits the token on the two dots, normalizes the Base64url alphabet (replacing - and _ with + and /, then re-padding with = to a multiple of 4), and runs each segment through the browser's built-in atob() function. The resulting JSON strings are parsed with JSON.parse and rendered as a key-value table. No third-party JWT library is loaded — the work is straightforward enough that browser primitives handle it.
Standard registered claims are decoded with extra context. Numeric date claims (exp, iat, nbf) are treated as Unix epoch seconds and converted to local time using new Date(value * 1000). The expiry indicator compares exp to Math.floor(Date.now() / 1000) and shows whether the token is currently valid or how long ago it lapsed.
Crucially, this tool does not verify signatures. Signature verification requires the secret (for HMAC algorithms like HS256) or the public key (for RS256, ES256, EdDSA). Putting either of those in a browser would defeat their purpose, so verification belongs on the server with a library like jsonwebtoken (Node), jose, PyJWT, or jjwt. Decoding without verifying is fine for inspection but never sufficient to trust a token.
Be aware of the alg: none vulnerability — older JWT libraries would accept a token whose header said "alg": "none" with no signature attached. Modern libraries reject this, but if you receive a token with that header value from a third party, treat it as suspicious. Likewise, watch for confused-deputy attacks where an HS256 token is verified with a public key as the HMAC secret.
The decoder also helps catch common mistakes: tokens missing the third segment (which means the issuer used an unsigned JWS), tokens whose payload contains stringified JSON instead of a JSON object, and tokens with kid (key ID) headers pointing at rotated keys. Each of those shows up clearly in the parsed view.
Everything runs locally. Your token is never sent to a server, logged, or stored. Closing the tab discards it. That said, a JWT payload often contains real user identifiers and scopes, so avoid pasting production tokens on shared machines or screen-recorded sessions.

Common Use Cases

01

API debugging

Inspect tokens returned by your auth server to confirm claims, audience, and expiry without writing throwaway scripts.

02

Auth integration work

Compare two providers' tokens side by side when migrating between identity systems like Auth0, Cognito, or Keycloak.

03

Token expiry triage

Determine whether a 401 response is caused by an expired exp claim or a missing scope before digging deeper.

04

Custom claim verification

Confirm that tenant IDs, roles, and feature flags your backend writes into tokens are actually present in production.

Frequently Asked Questions

All decoding happens in your browser using atob and JSON.parse. The token is not uploaded, logged, or stored. That said, JWT payloads frequently contain real user identifiers, so avoid pasting production tokens on shared or recorded screens.
No. Verification requires either the HMAC secret or the issuer's public key, neither of which should be exposed in a browser. Use a server-side library like jsonwebtoken, jose, or PyJWT, or run the token through your provider's introspection endpoint.
Anyone can decode a JWT — it is just Base64url. The signature is what proves the token was actually issued by the trusted authority and has not been altered. A valid-looking payload with an invalid signature must be rejected.
RFC 7519 defines iss (issuer), sub (subject), aud (audience), exp (expiration), iat (issued at), nbf (not before), and jti (JWT ID). OpenID Connect adds nonce, auth_time, acr, and amr on top of those.
JWT defines exp, iat, and nbf as NumericDate values: seconds since the Unix epoch (1970-01-01 UTC). The decoder multiplies by 1000 and feeds the result to JavaScript's Date constructor to render local time.
It means the token is unsigned. The JWS spec allows it for development, but accepting such tokens in production is a well-known vulnerability — many CVEs exist because libraries treated none as valid. Reject anything other than the algorithms your server explicitly allows.
Decoding only proves the token is well-formed. The server may be rejecting it because the signature does not match, the audience claim is wrong, the token is expired, or the kid no longer maps to a known key. Decoding rules out structural problems first.
Yes — that is JWE (JSON Web Encryption), a related but separate spec. JWE tokens have five segments instead of three, and the payload is unreadable without the recipient's key. This decoder targets JWS (signed) tokens; encrypted tokens will fail to parse.
kid is the key ID, a hint to the verifier about which key to use when an issuer rotates signing keys. The decoder displays it so you can check that the value matches an entry in your JWKS endpoint.
Yes. Once the page has loaded, decoding requires no network access — atob, JSON.parse, and Date are all built into the browser.

Step-by-step guide

How to decode a JWT token

Walk through every step with screenshots, format-specific tips, and the platform-by-platform limits you need to know.

Advertisement