What Is Base64 Encoding?
Base64 is one of the most widely used encoding schemes in software development. Whether you are embedding images in HTML, sending email attachments, or transmitting binary data through a JSON API, Base64 is the mechanism that makes it possible. This guide explains how Base64 works, when you should use it, and how to implement it in JavaScript and Python.
How Base64 Encoding Works
Base64 encoding converts binary data into a string of printable ASCII characters. It uses a 64-character alphabet consisting of uppercase letters (A-Z), lowercase letters (a-z), digits (0-9), and two additional symbols (+ and /). A padding character (=) is appended when the input length is not a multiple of three bytes.
The encoding process works in three steps. First, the input bytes are grouped into blocks of three (24 bits). Each 24-bit block is then split into four 6-bit groups. Finally, each 6-bit value is mapped to a character in the Base64 alphabet. Because three bytes of input produce four bytes of output, Base64-encoded data is roughly 33% larger than the original binary.
For example, the ASCII string Hello (5 bytes) becomes SGVsbG8= (8 characters) after Base64 encoding. The trailing = is padding because 5 is not evenly divisible by 3.
When to Use Base64 Encoding
Base64 is the right choice whenever you need to represent binary data in a context that only supports text. Here are the most common scenarios developers encounter.
Data URIs in HTML and CSS
Data URIs let you embed small files directly in your markup or stylesheets, eliminating an extra HTTP request. This is especially useful for icons, small SVGs, and tiny images that would otherwise require a separate round-trip to the server.
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUg..."
alt="Inline Base64 image" />
Keep data URIs small. For images larger than a few kilobytes, a standard URL with proper caching is almost always more efficient.
Email Attachments (MIME)
The SMTP protocol was designed for plain text. To send binary attachments like PDFs or images, email clients use MIME (Multipurpose Internet Mail Extensions), which Base64-encodes the attachment body. The receiving mail client decodes the Base64 content back into the original file. This process is handled transparently by email libraries, but understanding it helps when debugging delivery issues or inspecting raw email headers.
API Payloads and JSON
JSON does not natively support binary data. When an API needs to accept or return binary content — file uploads, cryptographic signatures, or image thumbnails — Base64 encoding is the standard approach. The binary content is encoded to a Base64 string, placed inside a JSON field, and decoded on the receiving end.
{
"filename": "report.pdf",
"content_type": "application/pdf",
"data": "JVBERi0xLjQKMSAwIG9iago8PAovVH..."
}
Storing Binary Data in Text Formats
Configuration files (YAML, TOML, XML), environment variables, and database text columns all share the same limitation: they handle strings, not raw bytes. Base64 bridges that gap. Kubernetes Secrets, for instance, store values as Base64-encoded strings so that certificates and keys can live alongside plain-text configuration.
Base64 Encoding in JavaScript
JavaScript provides built-in functions for Base64 encoding and decoding in both browser and Node.js environments.
Browser (btoa / atob)
// Encode a string to Base64
const encoded = btoa("Hello, Base64!");
console.log(encoded); // "SGVsbG8sIEJhc2U2NCE="
// Decode a Base64 string
const decoded = atob("SGVsbG8sIEJhc2U2NCE=");
console.log(decoded); // "Hello, Base64!"
Note that btoa and atob only handle Latin-1 characters. For Unicode strings, you need to encode to UTF-8 first:
// Encode Unicode to Base64
function encodeBase64(str) {
const bytes = new TextEncoder().encode(str);
const binary = Array.from(bytes, (b) => String.fromCodePoint(b)).join("");
return btoa(binary);
}
// Decode Base64 to Unicode
function decodeBase64(b64) {
const binary = atob(b64);
const bytes = Uint8Array.from(binary, (c) => c.codePointAt(0));
return new TextDecoder().decode(bytes);
}
console.log(encodeBase64("Hello, world!")); // Works with any Unicode
Node.js (Buffer)
// Encode a string to Base64
const encoded = Buffer.from("Hello, Base64!").toString("base64");
console.log(encoded); // "SGVsbG8sIEJhc2U2NCE="
// Decode a Base64 string
const decoded = Buffer.from("SGVsbG8sIEJhc2U2NCE=", "base64").toString("utf-8");
console.log(decoded); // "Hello, Base64!"
// Encode a file to Base64
const fs = require("fs");
const fileBase64 = fs.readFileSync("image.png").toString("base64");
console.log(fileBase64.substring(0, 40) + "...");
Base64 Encoding in Python
Python's standard library includes a base64 module that handles encoding and decoding for strings, bytes, and files.
import base64
# Encode a string to Base64
original = "Hello, Base64!"
encoded = base64.b64encode(original.encode("utf-8"))
print(encoded.decode("utf-8")) # "SGVsbG8sIEJhc2U2NCE="
# Decode a Base64 string
decoded = base64.b64decode(encoded).decode("utf-8")
print(decoded) # "Hello, Base64!"
# Encode a file to Base64
with open("image.png", "rb") as f:
file_base64 = base64.b64encode(f.read()).decode("utf-8")
print(file_base64[:40] + "...")
# URL-safe Base64 (replaces + with - and / with _)
url_safe = base64.urlsafe_b64encode(original.encode("utf-8"))
print(url_safe.decode("utf-8")) # "SGVsbG8sIEJhc2U2NCE="
The urlsafe_b64encode variant is particularly useful when the encoded string will appear in URLs, query parameters, or filenames where + and / characters would cause problems.
Base64 vs. Base64URL
Standard Base64 uses +, /, and = characters that are reserved in URLs and file paths. Base64URL solves this by replacing + with - and / with _, and often omitting the padding = characters entirely. JSON Web Tokens (JWTs) use Base64URL encoding for their header and payload segments, which is why JWT strings are safe to include in HTTP headers and URLs without additional escaping.
Common Mistakes to Avoid
Using Base64 for security. Base64 is not encryption. It provides no confidentiality. Anyone can decode a Base64 string instantly. If you need to protect data, use proper encryption (AES, RSA) or hashing (SHA-256) instead.
Encoding large files as data URIs. While data URIs eliminate an HTTP request, they bypass browser caching and increase HTML size. Keep inline Base64 content under a few kilobytes; use regular URLs for larger assets.
Forgetting the 33% size overhead. Base64-encoded data is always larger than the original. For bandwidth-sensitive applications, consider whether the binary data can be sent as a proper binary payload (multipart form data, Protocol Buffers, or MessagePack) instead of Base64-encoding it into JSON.
Double encoding. Applying Base64 encoding twice is a surprisingly common bug. If your decoded output looks like another Base64 string rather than the expected data, check whether your code or a library is encoding the input more than once.
Try It Yourself
Want to encode or decode Base64 strings right now? Use our free Base64 Encoder & Decoder tool. It runs entirely in your browser — nothing is sent to a server, so your data stays private.
Frequently Asked Questions
Is Base64 encoding the same as encryption?
No. Base64 is an encoding scheme, not encryption. It transforms binary data into ASCII text so it can be transmitted over text-based protocols. Anyone can decode Base64 without a key, so it provides no security or confidentiality. Never use Base64 to protect sensitive data — use proper encryption algorithms like AES instead.
Why does Base64 increase file size?
Base64 represents every 3 bytes of binary data as 4 ASCII characters, resulting in approximately a 33% increase in size. This overhead is the trade-off for being able to safely embed binary data in text-based formats like JSON, XML, HTML, and email messages.
What is the difference between Base64 and Base64URL?
Standard Base64 uses the characters + and / as part of its 64-character alphabet, and = for padding. Base64URL replaces + with - and / with _ to make the output safe for use in URLs and filenames without additional percent-encoding. Base64URL is commonly used in JWTs and data URIs in web applications.