Back to Blog
Base64EncodingWeb

How Base64 Encoding Works and When to Use It

March 15, 2026 · 5 min read

Open a JWT token, a CSS data URI, or an email with an attachment and you'll encounter Base64 — a wall of letters, numbers, and slashes that looks like noise but carries real data. Understanding Base64 will help you debug faster and use it correctly.

Why Base64 Exists

Computers communicate using bytes — values from 0 to 255. Many transmission systems (email protocols, URLs, HTML attributes, HTTP headers) were designed for plain text and can't reliably handle arbitrary binary data. Characters like null bytes, control characters, and non-ASCII values cause problems.

Base64 solves this by encoding binary data as a sequence of 64 "safe" ASCII characters: uppercase letters (A–Z), lowercase letters (a–z), digits (0–9), plus + and /, with = used for padding. The result is text that travels safely through any text-based system.

How the Encoding Works

Base64 takes 3 bytes of input (24 bits) and converts them to 4 ASCII characters (6 bits each). This is why Base64 output is always ~33% larger than the input — you're representing 3 bytes with 4 characters.

Input:   "Man"
ASCII:   77  97  110
Binary:  01001101 01100001 01101110

Split into 6-bit groups:
         010011  010110  000101  101110

Base64 index: 19, 22, 5, 46
Base64 chars:  T    W    F    u

Output: "TWFu"

If the input length isn't divisible by 3, = padding characters are added to make the output length a multiple of 4.

Encoding and Decoding in Code

JavaScript (browser)

// Encode
btoa("Hello, World!")     // "SGVsbG8sIFdvcmxkIQ=="

// Decode
atob("SGVsbG8sIFdvcmxkIQ==")  // "Hello, World!"

// For non-ASCII strings, use TextEncoder
const encoded = btoa(
  String.fromCharCode(...new TextEncoder().encode("Hello 🌍"))
);

Node.js

// Encode
Buffer.from("Hello, World!").toString("base64")
// "SGVsbG8sIFdvcmxkIQ=="

// Decode
Buffer.from("SGVsbG8sIFdvcmxkIQ==", "base64").toString("utf8")
// "Hello, World!"

Python

import base64

# Encode
base64.b64encode(b"Hello, World!")
# b'SGVsbG8sIFdvcmxkIQ=='

# Decode
base64.b64decode("SGVsbG8sIFdvcmxkIQ==")
# b'Hello, World!'

Common Use Cases

JSON Web Tokens (JWT)

A JWT consists of three Base64url-encoded sections separated by dots: header, payload, and signature. Base64url is a variant that replaces + with - and / with _ to make it URL-safe.

eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0In0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
^-- header           ^-- payload          ^-- signature

Data URIs (inline images in CSS/HTML)

/* Inline a small PNG directly in CSS */
background-image: url("data:image/png;base64,iVBORw0KGgo...");

HTTP Basic Authentication

# Encodes "username:password" as Base64
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=

Email attachments (MIME)

The MIME standard uses Base64 to encode binary file attachments so they can travel through email servers that only handle 7-bit ASCII.

What Base64 Is NOT

Base64 is not encryption. It is trivially reversible — anyone who sees a Base64 string can decode it immediately. Do not use Base64 to "protect" sensitive data. Use it only for encoding binary data for text-safe transport.

Similarly, Base64 is not compression — it makes data ~33% larger, not smaller.

Try It

Use the Text Tools on io9.me to encode and decode Base64 strings instantly in your browser — no libraries, no setup.