filemarkr
All ToolsGuides
filemarkr

60+ free developer tools that run entirely in your browser — JSON formatter, JWT decoder, Base64, diff checker, regex tester, hash generator and more. No upload, no sign-up, completely private.

JSON & Data

  • JSON Formatter
  • JSON Minifier
  • JSON Validator
  • JSON to CSV
  • CSV to JSON
  • JSON to YAML

Encode & Decode

  • Base64 Encode / Decode
  • Base64 to Image
  • Image to Base64
  • URL Encode / Decode
  • HTML Entity Encoder
  • JWT Decoder

Text Tools

  • Text Diff Checker
  • Case Converter
  • Word & Character Counter
  • Slug Generator
  • Remove Duplicate Lines
  • Sort Text Lines

Generators

  • UUID Generator
  • Password Generator
  • Lorem Ipsum Generator
  • QR Code Generator
  • Random Number Generator
  • NanoID Generator

Popular Guides

  • How to Format and Pretty-Print JSON (Without Breaking It)
  • How to Minify JSON and Shrink Your API Payloads
  • How to Validate JSON and Pinpoint the Exact Syntax Error
  • How to Convert JSON to CSV for Excel and Google Sheets
  • How to Convert CSV to JSON (With Proper Header Detection)
  • All guides →

Explore

  • All Tools
  • JSON Formatter
  • JWT Decoder
  • Diff Checker
  • UUID Generator

Company

  • About
  • Privacy
  • Terms
  • Sitemap

Our Promise

  • 100% in your browser
  • Zero uploads
  • No sign-up, always free

© 2026 filemarkr. Designed & developed by Naved Naik.  All processing happens locally in your browser.

All guides

Encode & Decode

How to Decode a JWT and Read Its Claims (Without a Library)

Understand the three parts of a JSON Web Token, decode the header and payload by hand, check expiry, and learn why decoding is not the same as verifying.

Try the toolJWT Decoder →

An auth request fails, or a session expires early, and you need to know what's actually inside the token your API is receiving. A JSON Web Token looks like opaque gibberish, but the interesting parts are just Base64-encoded JSON — you can read them in seconds once you know the structure.

The three parts of a JWT

A JWT is three Base64URL-encoded strings joined by dots: header.payload.signature. Take this standard example:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
  • The header says how the token is signed.
  • The payload holds the claims — who the user is, when the token expires.
  • The signature is a cryptographic check that proves the first two parts weren't tampered with.

Decoding it by hand

Split on the dots and Base64-decode the first two segments. There's one wrinkle: JWTs use Base64URL, which swaps +→- and /→_ and drops padding, so you convert those back before decoding:

const [h, p] = token.split('.');

const decode = (seg) =>
  JSON.parse(
    atob(seg.replace(/-/g, '+').replace(/_/g, '/'))
  );

console.log(decode(h));
// { alg: "HS256", typ: "JWT" }

console.log(decode(p));
// { sub: "1234567890", name: "John Doe", iat: 1516239022 }

The JWT Decoder does exactly this in your browser and lays out the header, payload, and timestamps side by side. Because it decodes locally and never transmits the token, it's safe to paste tokens that grant real access — something you should never do on a server-side or logging-based decoder.

Reading the standard claims

Several payload fields are registered claims with defined meanings. The time-based ones are Unix timestamps (seconds since 1970), which is why iat: 1516239022 looks cryptic:

  • iat — issued-at time.
  • exp — expiry time; after this the token should be rejected.
  • nbf — not-before; the token is invalid until this moment.
  • sub — subject, usually the user ID.
  • iss / aud — issuer and intended audience.

To check whether a token is expired, compare exp against the current time in seconds:

const { exp } = decode(p);
const isExpired = exp && Date.now() / 1000 > exp;
// convert to a readable date:
new Date(exp * 1000).toISOString();

The critical caveat: decoding is not verifying

Anyone can decode a JWT. Only the holder of the secret or private key can verify — or forge — one.

This is the single most important thing to understand. The header and payload are merely encoded, not encrypted; Base64 is reversible by design. The signature is what provides trust, and checking it requires the signing key and a crypto library on your server. So:

  • Never trust decoded claims for authorization without verifying the signature server-side. A decoder shows you what a token says, not whether it's genuine.
  • Never put secrets in the payload. Anyone who has the token can read every claim. No passwords, no API keys, no private data.
  • Mind clock skew. If exp checks fail intermittently, your server and client clocks may disagree; allow a few seconds of leeway.
  • Watch the alg field. A token claiming alg: "none" is a known attack vector — your verifier should reject it, not decode it as trusted.

Related tools

The payload is just JSON, so pipe it through the JSON Formatter to pretty-print a dense claims object. If you're working with the raw segments directly, the Base64 Encode / Decode tool decodes individual parts.

Conclusion

A JWT is not a black box — it's two chunks of Base64URL-encoded JSON and a signature. Split on the dots, convert the URL-safe characters, decode, and read the claims; convert exp from a Unix timestamp to check expiry. Just remember the line that trips up so many developers: decoding tells you what a token claims, and only signature verification tells you whether to believe it.

More guides

How to Format and Pretty-Print JSON (Without Breaking It)

Read

How to Minify JSON and Shrink Your API Payloads

Read

How to Validate JSON and Pinpoint the Exact Syntax Error

Read

How to Convert JSON to CSV for Excel and Google Sheets

Read