How to Decode JWT Tokens Using Base64 in JavaScript
JSON Web Tokens (JWTs) are widely used for authentication and information exchange. While verifying a JWT requires the secret or public key, decoding its contents to read the payload is straightforward — the header and payload are simply Base64Url-encoded JSON. This is useful for debugging, logging, and extracting claims on the client side.
JWT structure
A JWT is three dot-separated Base64Url-encoded strings:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 ← header . eyJ1c2VySWQiOiIxMjMiLCJyb2xlIjoiYWRtaW4ifQ ← payload . SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c ← signature
Decoding the payload in the browser
function decodeJwt(token) {
const parts = token.split('.');
if (parts.length !== 3) throw new Error('Invalid JWT format');
function base64UrlDecode(str) {
// Pad and normalise URL-safe chars
const base64 = str.replace(/-/g, '+').replace(/_/g, '/');
const padded = base64.padEnd(base64.length + (4 - base64.length % 4) % 4, '=');
const binary = atob(padded);
const bytes = Uint8Array.from(binary, c => c.charCodeAt(0));
return JSON.parse(new TextDecoder().decode(bytes));
}
return {
header: base64UrlDecode(parts[0]),
payload: base64UrlDecode(parts[1]),
// signature is binary — we just note it exists
signature: parts[2],
};
}
// Usage
const { header, payload } = decodeJwt(token);
console.log(payload.userId); // "123"
console.log(payload.role); // "admin"
console.log(payload.exp); // expiry timestamp (Unix seconds)Decoding in Node.js
function decodeJwtNode(token) {
const parts = token.split('.');
if (parts.length !== 3) throw new Error('Invalid JWT');
const decode = (str) => {
const base64 = str.replace(/-/g, '+').replace(/_/g, '/');
return JSON.parse(Buffer.from(base64, 'base64').toString('utf8'));
};
return { header: decode(parts[0]), payload: decode(parts[1]) };
}
const { payload } = decodeJwtNode(token);
console.log(payload);Reading the expiry time
const { payload } = decodeJwt(token);
if (payload.exp) {
const expiresAt = new Date(payload.exp * 1000); // exp is Unix seconds
const isExpired = Date.now() > payload.exp * 1000;
console.log('Expires:', expiresAt.toLocaleString());
console.log('Expired:', isExpired);
}Important security note
Decoding a JWT reads the contents but does NOT verify the signature. Never trust the claims in a JWT payload on the server without verifying the signature using your secret key or the issuer's public key. Use libraries like jsonwebtoken (Node.js) or jose for proper verification.
- Client-side decoding is fine for displaying the username or reading the expiry to auto-refresh tokens.
- Server-side, always use
jwt.verify()— neverjwt.decode()alone for access control decisions.
Decode Base64 strings instantly
You can paste any Base64Url-encoded JWT section directly into our Base64 Encoder / Decoder to read the raw JSON — useful for quick debugging without writing any code.