Security & Privacy

JWT Decoder

Decode and inspect JSON Web Tokens instantly. View decoded Header, Payload, Claims, and Expiration status offline in your browser.

100% Client-Side — Token is never transmitted to any server
Enter or paste a JWT token to decode
HEADER: Algorithm & Token Type
{}
PAYLOAD: Claims & Data
{}
SIGNATURE
Paste a token to inspect signature hash
Developer Reference

Core Algorithm & Standalone Script

Standalone, zero-dependency JavaScript implementation for decoding Base64Url JWT headers and payloads client-side.

// Standalone JWT Decoder & Claim Inspector (Vanilla JS)
function parseJwt(token) {
  if (!token || typeof token !== 'string') {
    throw new Error('Token string is empty or invalid');
  }
  const parts = token.trim().split('.');
  if (parts.length !== 3) {
    throw new Error('Invalid JWT format (expected 3 dot-separated parts)');
  }

  function base64UrlDecode(str) {
    let base64 = str.replace(/-/g, '+').replace(/_/g, '/');
    while (base64.length % 4 !== 0) base64 += '=';
    const jsonStr = decodeURIComponent(
      atob(base64)
        .split('')
        .map(c => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2))
        .join('')
    );
    return JSON.parse(jsonStr);
  }

  const header = base64UrlDecode(parts[0]);
  const payload = base64UrlDecode(parts[1]);
  const signature = parts[2];

  const nowSeconds = Math.floor(Date.now() / 1000);
  let isExpired = false;
  let timeRemaining = null;

  if (typeof payload.exp === 'number') {
    isExpired = payload.exp < nowSeconds;
    timeRemaining = payload.exp - nowSeconds;
  }

  return {
    header,
    payload,
    signature,
    isExpired,
    timeRemaining,
    issuedAtDate: payload.iat ? new Date(payload.iat * 1000) : null,
    expiryDate: payload.exp ? new Date(payload.exp * 1000) : null
  };
}