Base64 Encoding Explained: When and How to Use It

· 7 min read

What Is Base64 Encoding?

Base64 is a binary-to-text encoding scheme that converts binary data into a string of ASCII characters. It represents binary data using only 64 printable characters: A-Z, a-z, 0-9, +, and /, with = used for padding. This makes it safe to transmit binary data through text-only channels like email, JSON APIs, and HTML.

The name "Base64" comes from the 64-character alphabet used in the encoding. Unlike encryption, Base64 is not a security measure—it's simply a way to represent binary data as text. Anyone can decode Base64 back to its original form without any key or password.

Base64 is everywhere in modern web development: data URIs in HTML/CSS, email attachments (MIME), JWT tokens, API authentication headers, and embedded images. Understanding when and how to use it is a fundamental developer skill.

How Base64 Works Under the Hood

The encoding process converts every 3 bytes (24 bits) of input into 4 Base64 characters (6 bits each). Here's the step-by-step process:

# Step 1: Take 3 bytes of input
Input text: "Hi!"
Binary: 01001000 01101001 00100001

# Step 2: Split into 6-bit groups
010010 000110 100100 100001

# Step 3: Map each 6-bit group to Base64 alphabet
010010 → S (18)
000110 → G (6)
100100 → k (36)
100001 → h (33)

# Result: "Hi!" → "SGkh"

# Base64 alphabet (index 0-63):
# A-Z (0-25), a-z (26-51), 0-9 (52-61), + (62), / (63)

When the input length isn't divisible by 3, Base64 adds padding with = characters. One byte of input produces two Base64 characters plus ==, and two bytes produce three Base64 characters plus =.

# Padding examples
"A"    → "QQ=="   (1 byte → 2 chars + ==)
"AB"   → "QUI="   (2 bytes → 3 chars + =)
"ABC"  → "QUJD"   (3 bytes → 4 chars, no padding)

🛠️ Try it yourself

Base64 Encoder/Decoder → URL Encoder →

Encoding and Decoding in Practice

Every major programming language provides built-in Base64 support. Here's how to encode and decode in the most popular languages:

# JavaScript (Browser & Node.js)
btoa("Hello World")           // "SGVsbG8gV29ybGQ="
atob("SGVsbG8gV29ybGQ=")     // "Hello World"

// Node.js Buffer (handles Unicode)
Buffer.from("Hello").toString("base64")  // "SGVsbG8="
Buffer.from("SGVsbG8=", "base64").toString()  // "Hello"

# Python
import base64
base64.b64encode(b"Hello World")  # b'SGVsbG8gV29ybGQ='
base64.b64decode(b"SGVsbG8gV29ybGQ=")  # b'Hello World'

# Command line (Linux/Mac)
echo -n "Hello World" | base64        # SGVsbG8gV29ybGQ=
echo "SGVsbG8gV29ybGQ=" | base64 -d  # Hello World

# PHP
base64_encode("Hello World")   // "SGVsbG8gV29ybGQ="
base64_decode("SGVsbG8gV29ybGQ=")  // "Hello World"

Common Use Cases

Base64 encoding solves specific problems in data transmission. Here are the most important use cases:

1. Embedding Images in HTML/CSS (Data URIs)

Small images (icons, logos under 10KB) can be embedded directly in HTML or CSS, eliminating an HTTP request:

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

/* CSS background */
.icon { background-image: url(data:image/svg+xml;base64,PHN2ZyB4...); }

2. Email Attachments (MIME)

Email protocols (SMTP) were designed for 7-bit ASCII text. Base64 encoding allows binary files (images, PDFs, executables) to be transmitted as text within email messages. The MIME standard uses Base64 as its primary encoding for attachments.

3. API Authentication

HTTP Basic Authentication encodes credentials in Base64:

# Authorization header format
Authorization: Basic base64(username:password)

# Example
Authorization: Basic dXNlcjpwYXNz  # "user:pass"

# ⚠️ Base64 is NOT encryption! Always use HTTPS with Basic Auth

4. JWT Tokens

JSON Web Tokens use Base64URL encoding (URL-safe variant) for their header, payload, and signature sections:

# JWT structure: header.payload.signature
eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiam9obiJ9.abc123...

# Each section is Base64URL-encoded JSON
# Header: {"alg":"HS256"}
# Payload: {"user":"john"}

5. Storing Binary Data in JSON/XML

JSON and XML don't natively support binary data. Base64 encoding lets you embed files, images, or encrypted data within these text-based formats.

Base64 in APIs and Web Development

Modern APIs frequently use Base64 for file uploads, webhook payloads, and configuration data:

// File upload via JSON API
const fileData = await readFile("photo.jpg");
const base64Data = fileData.toString("base64");

fetch("/api/upload", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    filename: "photo.jpg",
    content: base64Data,
    contentType: "image/jpeg"
  })
});

// GitHub API: creating/updating files requires Base64 content
// Stripe API: webhook signatures use Base64
// AWS S3: pre-signed URLs include Base64-encoded policies

Performance Considerations

Base64 encoding comes with trade-offs that every developer should understand:

# Size comparison
Original file:  75,000 bytes (75 KB)
Base64 encoded: 100,000 bytes (100 KB) — 33% larger
Gzipped Base64:  76,000 bytes (76 KB) — compression helps but still bigger

# Rule of thumb: if size matters, transmit binary directly
# Use multipart/form-data instead of Base64 for large file uploads

Base64 Variants and URL-Safe Encoding

Standard Base64 uses + and / characters that have special meaning in URLs and filenames. Several variants exist to address this:

# Standard Base64 vs Base64URL
Standard:  "abc+/==" (contains +, /, =)
URL-safe:  "abc-_"   (URL-safe characters, no padding)

# URL encoding standard Base64 breaks it:
# "abc+/==" → "abc%2B%2F%3D%3D" (ugly and longer)
# Better to use Base64URL from the start

When working with URLs, query parameters, or filenames, always use the URL-safe Base64 variant. Our Base64 Encoder supports both standard and URL-safe encoding. For URL-specific encoding needs, check out our URL Encoder.

Key Takeaways

Related Tools

Base64 Encoder URL Encoder