Back to blog
Problem SolvingNovember 10, 2025

Base64: What It Is, When to Use It, and When Not To

Base64 encoding is misunderstood as encryption. It's not. Here's what it actually does and where it's legitimately useful.

Base64encodingdeveloper toolsdata

Base64 appears in API docs, image data URIs, email attachments, and JWTs. Developers use it regularly without always knowing exactly what it does or why. Let's clear it up.

What Base64 Is

Base64 is an encoding scheme that converts binary data into a string of 64 safe ASCII characters: A–Z, a–z, 0–9, +, and /.

The name comes from the character set size: 64 possible characters.

It was designed to transmit binary data through systems that only handle text specifically email systems, which historically choked on binary bytes.

What Base64 Is Not

Base64 is not encryption. It provides zero security. Anyone can decode a Base64 string instantly it's a completely reversible operation with no key or secret.

This is the most common misunderstanding. You will occasionally see developers Base64-encoding sensitive data under the impression it's "hiding" it. It's not. It's as hidden as a pig in sunglasses.

dXNlcm5hbWU6cGFzc3dvcmQ=

That's username:password in Base64. The spec for HTTP Basic Authentication literally does this openly both sides know it's Base64, and the value is decoded immediately upon receipt.

How It Works

Base64 takes 3 bytes of binary data at a time and converts them into 4 ASCII characters.

3 bytes = 24 bits → split into four 6-bit groups → each 6-bit group maps to one of 64 characters.

This means Base64 is always 4/3 the size of the original data about 33% larger. A 3 KB binary becomes roughly 4 KB in Base64.

The = characters at the end are padding they align the output when the input length isn't divisible by 3.

Practical Uses

1. Embedding images in HTML/CSS (data URIs)

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUh...">

Instead of a separate HTTP request for the image, you embed it directly in the HTML. Useful for tiny icons where the request overhead outweighs the size cost. Not useful for large images (bloats HTML significantly).

In CSS:

.icon {
  background-image: url("data:image/svg+xml;base64,PHN2Zy...");
}

2. Sending binary data in JSON

JSON is text-only. If an API needs to send a PDF, image, or any binary file inside a JSON response, Base64 encodes it:

{
  "filename": "report.pdf",
  "content": "JVBERi0xLjQKJcfs..."
}

The client decodes the Base64 string to get the binary file.

3. JWT (JSON Web Tokens)

JWTs consist of three Base64URL-encoded segments separated by dots: header, payload, signature.

eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiYWxpY2UifQ.abc123

Base64URL is a variant that replaces + with - and / with _ to make it safe for URLs and HTTP headers. The JWT decoder decodes these without needing a secret key for the header and payload.

4. Email attachments (MIME)

The SMTP email protocol transmits text. Attachments (PDFs, images, any binary) are Base64-encoded before transmission and decoded by the recipient's email client. This happens automatically you don't manage it manually unless building an email system.

5. API authentication headers

HTTP Basic Auth encodes username:password as Base64 in the Authorization header:

Authorization: Basic dXNlcjpwYXNzd29yZA==

Again, this is not security. HTTPS provides the security (the header is encrypted in transit). The Base64 is purely to make the header value safe for transport.

URL-Safe Base64

Standard Base64 uses + and /. These characters have special meanings in URLs. URL-safe Base64 (Base64URL) replaces:

  • +-
  • /_

And typically omits the padding = characters.

If you're encoding data for a URL parameter or HTTP header, use Base64URL. If you're encoding binary for storage or JSON, standard Base64 is fine.

When Not to Use Base64

Don't use it for security. It's trivially reversible.

Don't use it for large images in HTML. A 50 KB image base64-encoded is ~67 KB in the HTML. Plus it blocks caching (the HTML can't be cached independently of the image) and blocks lazy loading.

Don't use it to "compress" data. Base64 always makes data 33% larger. It's for format compatibility, not compression.

Don't use it as a substitute for proper binary transmission. Modern APIs, CDNs, and storage systems handle binary directly. Prefer multipart form uploads for files over Base64-encoding them in JSON.

Quick Reference

SituationUse Base64?
Tiny icon embedded in HTMLYes
Binary data inside JSON responseYes
JWT componentsYes (auto-handled by JWT libraries)
API auth headerYes (auto-handled by HTTP libraries)
"Hiding" a passwordNo use encryption
Compressing a fileNo use gzip/zstd
Sending a large image to an APINo use multipart upload
URLsYes, but use Base64URL variant

Encode and Decode in Your Browser

The Base64 encoder/decoder converts between text and Base64 instantly. No upload, no server, just conversion.

For encoding/decoding in code:

JavaScript:

btoa("hello world")          // encode: "aGVsbG8gd29ybGQ="
atob("aGVsbG8gd29ybGQ=")    // decode: "hello world"

For binary data (files, images), btoa/atob don't work directly on binary. Use TextEncoder or FileReader.readAsDataURL() depending on context.

Python:

import base64
base64.b64encode(b"hello world")  # b'aGVsbG8gd29ybGQ='
base64.b64decode("aGVsbG8gd29ybGQ=")  # b'hello world'

Use the Base64 encoder/decoder when you need quick conversion. For JWT decoding specifically, the JWT decoder handles the Base64URL encoding and formats the JSON payload cleanly.

Related articles