Base64 Encoding Explained: How It Works & When to Use It
September 26, 2026 · Web Development
You've seen it everywhere: the data:image/png;base64,iVBOR... in HTML, the gibberish middle of a JWT, email attachments that look like alphabet soup. Base64 is the internet's standard trick for squeezing arbitrary binary data through text-only channels. Here's how it works, when to use it — and the security misunderstanding to kill on sight.
What Base64 encoding is, in plain words
Many systems only safely carry plain text — email bodies, JSON strings, URLs, HTML attributes. But files, images, and encryption keys are binary: raw bytes that include control characters and values text channels mangle. Base64 solves this by re-encoding any bytes using only 64 safe ASCII characters: A–Z, a–z, 0–9, +, and / (with = as padding). The result is pure text that survives email, JSON, and copy-paste intact.
How it works: 3 bytes become 4 characters
The classic example: Man → TWFu.
- Take 3 bytes:
M(77),a(97),n(110) — 24 bits total. - Split the 24 bits into four 6-bit groups:
010011010110000101101110. - Each 6-bit value (0–63) maps to one alphabet character: 19→
T, 22→W, 5→F, 46→u.
That's the whole algorithm: regroup bits, look up characters. Decoding reverses it. The 6-bit grouping is why the alphabet has exactly 64 characters (2⁶ = 64).
Try it: encode Man yourself in our free Base64 Encoder/Decoder — then flip to URL-safe mode and decode it back.
Padding and the ~33% size overhead
Input isn't always a multiple of 3 bytes. Leftover bytes get padded with =: Ma (2 bytes) → TWE=, M (1 byte) → TQ==. The padding tells the decoder how many bytes the last group really held.
The price: every 3 bytes become 4 characters, so Base64 output is always about 33% larger than the input. It's a feature, not a bug — you're buying text-safety with size — but it means Base64 is the wrong choice when size matters and the channel already handles binary (like a file upload).
Base64 vs Base64URL: when to use which
| Standard Base64 | Base64URL | |
|---|---|---|
| Characters 62–63 | + and / | - and _ |
| Padding | = kept | Usually dropped |
| Use in | Email (MIME), data URLs, XML | URLs, filenames, JWTs |
+ means "space" in query strings and / separates URL paths — so standard Base64 in a URL gets corrupted unless percent-encoded (defeating the purpose). Base64URL exists precisely for that case. Rule of thumb: if the output touches a URL, use Base64URL.
Where Base64 shows up
- Data URLs —
data:image/png;base64,...embeds small images directly in HTML/CSS. - JWTs — the header and payload are base64url-encoded (readable, not encrypted — see our JWT guide).
- Email — MIME encodes attachments as Base64 so they survive text-only mail transport.
- JSON APIs — JSON has no binary type, so APIs Base64-encode files and keys inside JSON payloads.
- HTTP Basic Auth —
Authorization: Basic dXNlcjpwYXNzis justuser:passin Base64. Obfuscation, not security — always over HTTPS.
Encoding is not encryption
The single most important sentence in this article: Base64 provides zero confidentiality. It's a format conversion, like writing a number in hexadecimal — anyone who recognizes it reverses it instantly. Every "I Base64-encoded the password before storing it" is a vulnerability report waiting to happen. If data must be secret, encrypt it (AES, TLS) or hash it (bcrypt, Argon2) — encoding is for transport, never for protection.
Common mistakes
btoa()and Unicode: JavaScript'sbtoa()throws on anything outside Latin-1 — emoji, Chinese, Arabic, even some European characters. Encode to UTF-8 bytes first (TextEncoder), then Base64 those bytes; reverse withTextDecoderon decode.- Double encoding: encoding an already-encoded string produces valid-looking output that decodes to garbage. If your output has suspicious length or decodes to more Base64, you've encoded twice.
- Huge data URLs: inlining a 2MB image as Base64 bloats your HTML by ~2.7MB, blocks parsing, and can't be cached separately. Reserve data URLs for tiny assets (icons under a few KB).
- Base64 vs percent-encoding: they're different tools — Base64 packs binary into text; percent-encoding (
%20) escapes reserved characters within text that's already text. Don't Base64 a URL when you meant to percent-encode it (and vice versa).
Frequently asked questions
- Why does Base64 end with =?
- Padding. Base64 works on 3-byte groups; if your input isn't a multiple of 3 bytes, `=` characters pad the last group out to 4 characters. One trailing byte → `==`, two trailing bytes → `=`. The `=` carries no data — it just marks how much padding was added.
- Is Base64 secure?
- No. Base64 is an encoding, not encryption — anyone can decode it instantly. It provides zero confidentiality. Never "protect" passwords, tokens, or personal data with Base64; use real encryption or hashing instead.
- Why is Base64 bigger than the original?
- It represents every 3 bytes as 4 characters, so output is ~33% larger than input (plus padding). That overhead is the price of restricting output to 64 safe ASCII characters.
- What's Base64URL for?
- Standard Base64 uses `+`, `/`, and `=` — characters with special meaning in URLs. Base64URL swaps them for `-` and `_` and drops padding, so encoded values survive in query strings, filenames, and JWTs without percent-encoding.
- Why does btoa() fail on emoji?
- JavaScript's `btoa()` only accepts Latin-1 (single-byte) characters; emoji and most non-English text are multi-byte UTF-8 and throw "InvalidCharacterError". The fix is encoding the string to UTF-8 bytes first (e.g. via TextEncoder), then Base64-encoding the bytes.
- Can I put images in HTML with Base64?
- Yes, via data URLs (`<img src="data:image/png;base64,...">`), and it's handy for tiny icons — one fewer HTTP request. But the ~33% size overhead makes it a bad deal for large images; files above a few KB are usually better as separate requests (which also cache independently).
- How do I decode Base64?
- In JavaScript: `atob()` (ASCII/Latin-1 only — use TextDecoder for UTF-8). In Python: `base64.b64decode()`. On the command line: `echo "TWFu" | base64 -d`. Or paste it into our Base64 Encoder/Decoder tool — no code needed.
Related articles
UUID v4 vs v7: Which Version Should You Use?
Random vs time-ordered UUIDs: how v7 fixes database index fragmentation, and when v4 is still the right call.
Web DevelopmentURL Encoding (Percent-Encoding) Explained
Why spaces become %20, when to encode (and what never to encode), plus the classic + vs %20 and double-encoding traps.
Web DevelopmentRegex Cheat Sheet: Patterns, Flags & Examples
The regex syntax you actually use — character classes, quantifiers, groups, anchors, and flags — with copy-paste examples and honest caveats.