Base64 is one of the most widely used encodings on the web, and one of the most misunderstood. It shows up inside JWT tokens, email attachments, data URLs, API payloads, SSH keys and TLS certificates. Yet many developers first meet it when something breaks — a JWT that won't decode, a PNG embedded in CSS that renders as a broken image, or an API that refuses a binary upload. This guide walks through what Base64 actually is, why it was invented, and when you should — and should not — reach for it.

What Base64 does

At its core, Base64 takes arbitrary binary data and re-expresses it using only 64 safe, printable ASCII characters: A–Z, a–z, 0–9, plus + and /. Any three input bytes (24 bits) become four output characters (6 bits each). The result is roughly 33% larger than the input but it contains nothing that will confuse a text-oriented system: no newlines, no control characters, no non-ASCII bytes.

Why it exists

Early email protocols (SMTP, MIME) were built around 7-bit ASCII text. If you wanted to attach a PDF or a photo, the raw binary would be corrupted by intermediate mail servers that happily stripped a high bit or inserted a stray carriage return. Base64 solved the problem by making binary look like boring text. The same issue reappeared for JSON payloads, URL parameters, HTTP headers and XML bodies — anywhere that assumes text. Base64 is the universal adapter.

Common use cases today

Base64 is not encryption

This deserves its own section because the mistake is common and costly. Base64 has no secret: anyone with the encoded string can decode it in one browser console call. Never use it to protect passwords, API keys, or user data. If you see credentials "obfuscated" with Base64 in source code, treat them as plaintext. Use real encryption (AES, NaCl, libsodium) for anything you actually need to keep secret.

Variants to be aware of

Standard Base64 uses + and / which are unsafe in URLs. base64url replaces those with - and _ and drops the = padding — that's what JWTs and modern web APIs use. There are also MIME-specific line-wrapped variants (76-character lines) and older mis-implementations you'll occasionally see. When in doubt, check whether the decoder accepts the exact alphabet your source produced.

Size overhead

Three bytes in, four characters out. The exact overhead is 4⁄3 = ~33% before any padding or line wrapping. For small inline assets this is usually worth it; for anything larger than a few kilobytes, consider a separate HTTP request instead.

When to reach for it

Reach for Base64 when binary data must travel through a text-only channel and size isn't critical. Reach for real encryption when confidentiality matters. And when you're debugging — paste into a Base64 decoder first before assuming the token itself is broken; nine times out of ten the token is fine and the system that unpacked it has a different expectation about padding or alphabet.