Encoding8 min read

What Is Base64 Encoding and How Does It Work?

Base64 is everywhere in web development, but many developers use it without fully understanding what's happening under the hood. This guide breaks down the algorithm, explores real-world use cases, and helps you decide when to use it—and when to avoid it.

What Is Base64 and Why Does It Exist?

Base64 is an encoding scheme that converts binary data into a text-based format using only 64 printable ASCII characters. These 64 characters are: uppercase letters (A-Z), lowercase letters (a-z), digits (0-9), plus (+), and forward slash (/). An equals sign (=) is used for padding.

But why do we need this? The internet was originally designed to transmit text, not binary data. Before Base64, sending images, files, or other binary data over email or HTTP was problematic. Many systems would corrupt binary data because they expected text-only content. Base64 solved this by encoding binary data into text that could safely travel through any system without corruption.

Today, even though modern systems handle binary data fine, Base64 remains useful for embedding data directly in text formats like JSON, HTML, CSS, and URLs.

How Base64 Encoding Actually Works

Base64 encoding converts every 3 bytes of input into 4 characters of output. Here's the step-by-step process:

Step 1: Break Input Into 3-Byte Chunks

Take your input data and split it into groups of 3 bytes (24 bits). If the input isn't a multiple of 3, the last group will have fewer bytes—we'll handle that with padding.

Step 2: Split Each 24-Bit Chunk Into Four 6-Bit Groups

Each 3-byte chunk (24 bits) is split into four 6-bit groups. Six bits can represent numbers from 0–63 (2^6 = 64 possible values).

Example: Letter "A" = 65 (ASCII) = 01000001 (binary)
+ Next 2 bytes from input = 24 bits total
24 bits → split into four 6-bit groups

Step 3: Map Each 6-Bit Group to the Base64 Alphabet

Use the 6-bit value as an index into the Base64 alphabet:

A-Z (0-25), a-z (26-51), 0-9 (52-61), + (62), / (63)

So if a 6-bit group equals 5, it maps to 'F'. If it equals 28, it maps to 'c'.

Step 4: Handle Padding

If the input isn't a multiple of 3 bytes, pad with zeros and mark the output with equals signs:

• 1 remaining byte → 2 output characters + "=="
• 2 remaining bytes → 3 output characters + "="

Real Example:

Input: "Hi" (2 bytes)

Hex: 0x48 0x69 → Binary: 01001000 01101001

Split into 6-bit: 010010 | 000110 | 100100 (pad)

Decimal: 18 | 6 | 36 → Map to Base64: S | G | k

Output: "SGk=" (with padding)

Common Use Cases: Where Base64 Shines

1. Data URIs in HTML and CSS

Embed small images directly into HTML or CSS without external requests. This avoids extra HTTP round trips and can improve page load time for tiny assets.

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

Downside: The URI becomes long and non-human-readable.

2. Email Attachments (MIME)

Email servers originally expected 7-bit ASCII text. To attach files (images, PDFs, etc.), they must be Base64 encoded. The MIME standard uses Base64 for all non-text attachments.

3. JWT (JSON Web Tokens)

JWTs use Base64URL encoding (a variant we'll cover next) to encode the header and payload. The token becomes a compact string safe for URLs and HTTP headers.

eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI...Mm9MJ.TJVA

4. API Payloads and Configuration

When you need to embed binary data in JSON requests (like sending file data to an API), Base64 is the standard. It keeps the payload valid JSON without character escaping issues.

5. Password/Credential Storage in Transit

Although Base64 is not encryption, it's often used to safely transmit credentials in HTTP Basic Authentication headers. Always combine with HTTPS.

URL-Safe Base64: The Variant You Should Know About

Standard Base64 uses + and / characters, which have special meaning in URLs. The + means space, and / is a path separator. This causes problems when you try to pass Base64 data in URL query parameters.

URL-safe Base64 (also called Base64URL) swaps these characters:

Standard: + and /
URL-safe: - (hyphen) and _ (underscore)

JWTs, OAuth 2.0 PKCE, and other web standards use Base64URL. JavaScript has built-in methods for this:

btoa("Hello") // Standard: SGVsbG8=
btoa("Hello").replace(/\+/g, '-').replace(/\//g, '_')
// URL-safe: SGVsbG8=

The Size Overhead: What You're Trading

Here's the trade-off you're making with Base64: every 3 bytes of input becomes 4 bytes of output. That's a 33% overhead.

Example:

Original image: 300 KB
Base64 encoded: 400 KB (33% larger)

This overhead matters when:

  • Bandwidth is limited: Encoding large files balloons their size unnecessarily
  • Network latency is critical: Sending 33% more data takes longer
  • Storage is a constraint: Databases or caches store the larger encoded version

The overhead is worth it when the convenience of embedding data directly in text formats outweighs the size cost.

When NOT to Use Base64

Base64 is useful, but it's not a solution to every problem. Avoid it when:

1. Large Files

Never encode a 100 MB file to Base64. The 33% overhead means you'll create a 133 MB payload. Use binary transfer instead (HTTP multipart/form-data for file uploads).

2. When Binary Transport Is Available

Modern HTTP supports binary content natively. If you're building an API, send images as image/png and files as application/octet-stream. No encoding needed.

3. Security

Base64 is not encryption. Anyone can decode it instantly. Never use it to hide sensitive data. Use encryption (AES, TLS) instead.

4. Hashing

Don't use Base64 for checksums or fingerprints. Use proper hash functions (SHA-256, MD5). Base64 is just an encoding, not a hash.

5. When the Format Has Native Binary Support

Protocol Buffers, MessagePack, and BSON handle binary data natively without encoding. Use them for APIs where efficiency matters.

Quick Reference: Base64 in Practice

Encoding in JavaScript

const text = "Hello, World!"
const encoded = btoa(text)
console.log(encoded) // "SGVsbG8sIFdvcmxkIQ=="

Decoding in JavaScript

const encoded = "SGVsbG8sIFdvcmxkIQ=="
const decoded = atob(encoded)
console.log(decoded) // "Hello, World!"

Encoding in Python

import base64
text = "Hello, World!"
encoded = base64.b64encode(text.encode())
print(encoded) # b'SGVsbG8sIFdvcmxkIQ=='

Try It Yourself

Want to experiment with Base64 encoding and decoding? Try our free Base64 Encoder tool:

Use it to encode text, files, or data URIs. See how the output changes with different inputs and understand Base64 in action.

Key Takeaways

  • Base64 converts binary data to printable ASCII text using 64 characters
  • • Every 3 bytes become 4 characters (33% overhead)
  • • Use it for: data URIs, email attachments, JWTs, API payloads
  • URL-safe Base64 swaps + and / for - and _
  • Don't use it for: large files, encryption, hashing, or when binary transport is available
  • • It's an encoding, not encryption—anyone can decode it

Have feedback on this guide? Found an error? Let us know on GitHub.