Base64 is a binary-to-text encoding that represents binary data using 64 ASCII characters. It is used in data URIs, JWT tokens, email attachments (MIME), API authentication, and Kubernetes secrets. Base64 increases data size by ~33% and is NOT encryption. Use our free online tool to encode and decode Base64 instantly.
- Base64 converts 3 bytes of binary data into 4 ASCII characters, resulting in a ~33% size increase.
- In JavaScript, use btoa()/atob() in browsers and Buffer in Node.js. For Unicode, encode to UTF-8 first.
- Base64URL replaces + with - and / with _ for safe use in URLs, filenames, and JWT tokens.
- Base64 is encoding, NOT encryption. Anyone can decode it without a key. Never use it for security.
- For files larger than 5-10KB, prefer binary transfer methods (multipart/form-data) over Base64 embedding.
- Common real-world uses: data URIs, JWT tokens, HTTP Basic Auth, MIME email, Kubernetes secrets, CSS embedding.
Try our free Base64 Encoder/Decoder tool β
What Is Base64 Encoding and Why Does It Exist?
Base64 is a binary-to-text encoding scheme defined in RFC 4648. It converts arbitrary binary data into a string of printable ASCII characters using a 64-character alphabet: A-Z (26), a-z (26), 0-9 (10), + (1), and / (1), plus = for padding.
Base64 was created to solve a fundamental problem: many systems and protocols (email via SMTP, HTML, JSON, XML, HTTP headers) were designed to handle only text data. When you need to transmit binary data (images, files, certificates, encrypted blobs) through these text-only channels, you need a way to represent binary as text. That is exactly what Base64 does.
The encoding process takes every 3 bytes (24 bits) of input and splits them into four 6-bit groups. Each 6-bit value (0-63) maps to one character in the Base64 alphabet. If the input length is not a multiple of 3, the output is padded with = characters to make its length a multiple of 4.
Base64 Alphabet (RFC 4648):
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z (0-25)
a b c d e f g h i j k l m n o p q r s t u v w x y z (26-51)
0 1 2 3 4 5 6 7 8 9 (52-61)
+ / (62-63)
= (padding)
Encoding example: "Hi" (2 bytes, needs padding)
H = 0x48 = 01001000
i = 0x69 = 01101001
Binary: 010010 000110 100100 (pad)
Index: 18 6 36 =
Char: S G k =
Result: "SGk="Base64 Encoding and Decoding in JavaScript
JavaScript provides built-in Base64 functions in both browser and Node.js environments. Here are the essential methods you need to know:
Browser: btoa() and atob()
btoa() encodes a string to Base64, and atob() decodes Base64 back to a string. These functions only handle ASCII (Latin-1) characters in the browser.
// Encode to Base64
const encoded = btoa("Hello, World!");
console.log(encoded); // "SGVsbG8sIFdvcmxkIQ=="
// Decode from Base64
const decoded = atob("SGVsbG8sIFdvcmxkIQ==");
console.log(decoded); // "Hello, World!"
// Check if a string is valid Base64
function isBase64(str) {
try {
return btoa(atob(str)) === str;
} catch (e) {
return false;
}
}Handling Unicode in the Browser
Since btoa() throws an error on non-ASCII characters, you need to encode Unicode text to UTF-8 first. Here are two approaches:
// Method 1: TextEncoder (modern browsers)
function toBase64Unicode(str) {
const bytes = new TextEncoder().encode(str);
const binStr = Array.from(bytes, b => String.fromCodePoint(b)).join("");
return btoa(binStr);
}
function fromBase64Unicode(b64) {
const binStr = atob(b64);
const bytes = Uint8Array.from(binStr, c => c.codePointAt(0));
return new TextDecoder().decode(bytes);
}
// Method 2: encodeURIComponent (legacy support)
const encoded = btoa(unescape(encodeURIComponent("δ½ ε₯½δΈη")));
const decoded = decodeURIComponent(escape(atob(encoded)));Node.js: Buffer
In Node.js, the Buffer class handles Base64 encoding natively and supports any encoding including UTF-8:
// Node.js: Encode
const encoded = Buffer.from("Hello, World!").toString("base64");
// "SGVsbG8sIFdvcmxkIQ=="
// Node.js: Decode
const decoded = Buffer.from("SGVsbG8sIFdvcmxkIQ==", "base64").toString();
// "Hello, World!"
// Node.js: Unicode works natively
const unicodeB64 = Buffer.from("δ½ ε₯½δΈη").toString("base64");
const unicodeStr = Buffer.from(unicodeB64, "base64").toString("utf-8");
// Node.js: Base64URL encoding
const urlSafe = Buffer.from("data").toString("base64url");
// No + / or = charactersFile to Base64 in the Browser (FileReader)
To convert a file (image, PDF, etc.) to Base64 in the browser, use the FileReader API:
function fileToBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result);
reader.onerror = reject;
reader.readAsDataURL(file); // Returns "data:mime/type;base64,..."
});
}
// Usage with an input element
const input = document.querySelector("input[type=file]");
input.addEventListener("change", async (e) => {
const file = e.target.files[0];
const dataUrl = await fileToBase64(file);
console.log(dataUrl);
// "data:image/png;base64,iVBORw0KGgo..."
});Try our free Base64 Encoder/Decoder tool β
Base64 Encoding and Decoding in Python
Python includes the base64 module in its standard library. It supports standard Base64, URL-safe Base64, and several other encoding variants:
Basic Encode and Decode
import base64
# Encode a string (must be bytes)
encoded = base64.b64encode(b"Hello, World!")
print(encoded) # b'SGVsbG8sIFdvcmxkIQ=='
# Decode back to bytes
decoded = base64.b64decode(encoded)
print(decoded) # b'Hello, World!'
# String to Base64 string (common pattern)
text = "Hello, World!"
b64_str = base64.b64encode(text.encode("utf-8")).decode("ascii")
print(b64_str) # "SGVsbG8sIFdvcmxkIQ=="
# Unicode works via UTF-8
unicode_b64 = base64.b64encode("δ½ ε₯½δΈη".encode("utf-8"))
print(unicode_b64) # b'5L2g5aW95LiW55WM'URL-Safe Base64
import base64
# URL-safe Base64 (replaces + with - and / with _)
data = b"subjects?abcd"
standard = base64.b64encode(data)
urlsafe = base64.urlsafe_b64encode(data)
print(standard) # b'c3ViamVjdHM/YWJjZA=='
print(urlsafe) # b'c3ViamVjdHM_YWJjZA=='
# Note: / became _
# Decode URL-safe Base64
original = base64.urlsafe_b64decode(urlsafe)
print(original) # b'subjects?abcd'Encoding Files
import base64
# Encode a file to Base64
with open("image.png", "rb") as f:
encoded = base64.b64encode(f.read()).decode("ascii")
print(f"data:image/png;base64,{encoded[:50]}...")
# Decode Base64 back to a file
with open("output.png", "wb") as f:
f.write(base64.b64decode(encoded))
# One-liner for reading + encoding
b64 = base64.b64encode(open("doc.pdf", "rb").read()).decode()Base64 on the Command Line
Every major operating system provides built-in tools for Base64 encoding and decoding directly from the terminal:
Linux (GNU coreutils)
The base64 command is available on most Linux distributions. Use -w 0 to disable line wrapping:
# Encode a string (use -n to avoid trailing newline!)
echo -n "Hello, World!" | base64
# SGVsbG8sIFdvcmxkIQ==
# Decode a string
echo "SGVsbG8sIFdvcmxkIQ==" | base64 -d
# Hello, World!
# Encode a file (no line wrapping)
base64 -w 0 image.png > image.b64
# Decode a file
base64 -d image.b64 > image_restored.png
# Pipe from curl
curl -s https://example.com/api | base64 -w 0macOS (BSD base64)
macOS uses the BSD version with slightly different flags. The decode flag is -D (uppercase) instead of -d:
# Encode a string
echo -n "Hello, World!" | base64
# SGVsbG8sIFdvcmxkIQ==
# Decode (note: uppercase -D on macOS)
echo "SGVsbG8sIFdvcmxkIQ==" | base64 -D
# Hello, World!
# Encode a file
base64 -i image.png -o image.b64
# Decode a file
base64 -D -i image.b64 -o image_restored.pngOpenSSL (Cross-Platform)
OpenSSL provides a consistent Base64 interface across Linux, macOS, and Windows (via Git Bash or WSL):
# Encode with OpenSSL
echo -n "Hello, World!" | openssl base64
# SGVsbG8sIFdvcmxkIQ==
# Decode with OpenSSL
echo "SGVsbG8sIFdvcmxkIQ==" | openssl base64 -d
# Hello, World!
# Encode a file
openssl base64 -in image.png -out image.b64
# Decode a file
openssl base64 -d -in image.b64 -out image_restored.png
# One line (no wrapping) - pipe through tr
echo -n "Hello" | openssl base64 | tr -d "\n"Windows PowerShell
PowerShell uses .NET methods for Base64 operations:
# PowerShell: Encode
$bytes = [System.Text.Encoding]::UTF8.GetBytes("Hello, World!")
[Convert]::ToBase64String($bytes)
# SGVsbG8sIFdvcmxkIQ==
# PowerShell: Decode
$decoded = [Convert]::FromBase64String("SGVsbG8sIFdvcmxkIQ==")
[System.Text.Encoding]::UTF8.GetString($decoded)
# Hello, World!
# PowerShell: Encode a file
$fileBytes = [IO.File]::ReadAllBytes("C:\path\to\image.png")
[Convert]::ToBase64String($fileBytes) | Out-File image.b64Data URIs: Embedding Images as Base64
A Data URI lets you embed file data directly in HTML or CSS, eliminating the need for a separate HTTP request. The format is:
data:[<mediatype>][;base64],<data>
Examples:
data:text/plain;base64,SGVsbG8=
data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...
data:application/pdf;base64,JVBERi0xLjQK...This technique is most useful for small assets (icons, tiny images, SVGs) under 5KB. For larger files, the 33% Base64 overhead and the inability to cache the embedded data separately make regular file URLs a better choice.
Inline Image in HTML
<!-- Inline a small PNG icon -->
<img
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB
CAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII="
alt="1x1 pixel"
width="16"
height="16"
/>
<!-- Inline a small GIF -->
<img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
alt="transparent pixel"
/>Background Image in CSS
.icon-check {
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxu...);
background-size: contain;
width: 24px;
height: 24px;
}
@font-face {
font-family: "CustomIcon";
src: url(data:font/woff2;base64,d09GMgABAAAAA...) format("woff2");
}SVG Data URI (No Base64 Needed)
SVGs are already text, so you can use a URL-encoded data URI without Base64 encoding, which is smaller:
/* SVG as URL-encoded data URI (smaller than Base64) */
.icon {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z'/%3E%3C/svg%3E");
}Try our free Base64 Encoder/Decoder tool β
Base64 in APIs and Authentication
Base64 plays a critical role in several API patterns:
HTTP Basic Authentication
HTTP Basic Auth encodes the username:password pair as a Base64 string in the Authorization header. This is NOT secure on its ownβalways use HTTPS:
// HTTP Basic Authentication
const username = "admin";
const password = "secret123";
const credentials = btoa(username + ":" + password);
fetch("https://api.example.com/data", {
headers: {
"Authorization": "Basic " + credentials
// Authorization: Basic YWRtaW46c2VjcmV0MTIz
}
});
// curl equivalent
// curl -u admin:secret123 https://api.example.com/data
// curl -H "Authorization: Basic YWRtaW46c2VjcmV0MTIz" https://api.example.com/dataFile Uploads via JSON
When an API requires file uploads via JSON (rather than multipart/form-data), the file is typically Base64-encoded:
// File upload via JSON API
const fileInput = document.querySelector("input[type=file]");
const file = fileInput.files[0];
const reader = new FileReader();
reader.onload = () => {
const base64Data = reader.result.split(",")[1]; // Remove data URI prefix
fetch("https://api.example.com/upload", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
filename: file.name,
contentType: file.type,
data: base64Data // Base64-encoded file contents
})
});
};
reader.readAsDataURL(file);JWT (JSON Web Tokens)
JWTs consist of three Base64URL-encoded segments separated by dots: header.payload.signature. The header and payload are JSON objects encoded with Base64URL (not standard Base64):
// JWT structure: header.payload.signature
// Each part is Base64URL-encoded
// Decode a JWT payload (without verification)
function decodeJwtPayload(token) {
const payload = token.split(".")[1];
// Base64URL to standard Base64
const base64 = payload.replace(/-/g, "+").replace(/_/g, "/");
const padded = base64 + "=".repeat((4 - base64.length % 4) % 4);
return JSON.parse(atob(padded));
}
const token = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U";
console.log(decodeJwtPayload(token));
// { sub: "1234567890" }Base64URL-Safe Encoding vs Standard Base64
Standard Base64 uses + and / characters, which have special meaning in URLs (+ means space, / is a path separator). Base64URL (RFC 4648 Section 5) replaces these characters to be URL-safe:
| Character | Standard Base64 | Base64URL |
|---|---|---|
| 62nd character | + | - (hyphen) |
| 63rd character | / | _ (underscore) |
| Padding | = | Usually omitted |
Base64URL is used in JWT tokens, URL query parameters, filenames, and anywhere Base64 data appears in URLs. Many languages provide built-in URL-safe Base64 functions:
// JavaScript: Convert standard Base64 to Base64URL
function toBase64Url(base64) {
return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
}
function fromBase64Url(base64url) {
let base64 = base64url.replace(/-/g, "+").replace(/_/g, "/");
const pad = base64.length % 4;
if (pad) base64 += "=".repeat(4 - pad);
return base64;
}
// Node.js: Built-in Base64URL support
Buffer.from("data").toString("base64url"); // No + / or = chars
// Python
import base64
base64.urlsafe_b64encode(b"data") # b'ZGF0YQ=='
// Command line: Convert with tr
echo -n "data" | base64 | tr '+/' '-_' | tr -d '='Performance Considerations: The 33% Size Increase
Base64 encoding increases data size by approximately 33% because it represents every 3 bytes as 4 characters (4/3 = 1.333). This has real-world implications:
- Network bandwidth: A 1MB image becomes ~1.37MB when Base64-encoded. On mobile networks, this adds up quickly.
- Page weight: Base64 images embedded in HTML/CSS cannot be cached separately. Every page load re-downloads the encoded data.
- Memory usage: The browser must decode the Base64 string into binary, so both the encoded string and decoded binary exist in memory simultaneously.
- Compression penalty: Base64-encoded data compresses poorly because encoding destroys the patterns that gzip/brotli rely on. Always compress BEFORE encoding.
- CPU overhead: While encoding/decoding is fast for small data, processing millions of Base64 strings (e.g., in ETL pipelines) adds measurable latency.
| Original Size | Base64 Size | Overhead | Recommendation |
|---|---|---|---|
| 1 KB | 1.37 KB | +370 bytes | OK for data URIs |
| 10 KB | 13.7 KB | +3.7 KB | Consider file URL instead |
| 100 KB | 137 KB | +37 KB | Use binary transfer |
| 1 MB | 1.37 MB | +370 KB | Always use binary transfer |
Rule of thumb: Use Base64 data URIs for images under 5KB. For anything larger, serve the file separately and let the browser cache it.
Security Warning: Base64 Is NOT Encryption
See also: URL encoding guide
This is one of the most common misconceptions in software development: Base64 encoding provides zero security. It is a reversible encoding, not encryption. Anyone can decode a Base64 string instantly without any key or password.
Never use Base64 to "protect" sensitive data like passwords, API keys, tokens, or personal information. If you see Base64 used in a security context (like Kubernetes secrets), it is for encoding purposes only, not protection.
For actual security, use:
- Encryption: AES-256-GCM, ChaCha20-Poly1305, or RSA for data protection
- Hashing: bcrypt, Argon2, or scrypt for passwords (with salt)
- HTTPS/TLS: For data in transit
- Signed tokens: HMAC-SHA256 for data integrity verification
// WRONG: Base64 is NOT security
const encoded = btoa("my-secret-password");
// Anyone can do: atob("bXktc2VjcmV0LXBhc3N3b3Jk") => "my-secret-password"
// RIGHT: Use proper encryption
// Node.js example with AES-256-GCM
const crypto = require("crypto");
const key = crypto.randomBytes(32);
const iv = crypto.randomBytes(12);
const cipher = crypto.createCipheriv("aes-256-gcm", key, iv);
let encrypted = cipher.update("my-secret-password", "utf8", "base64");
encrypted += cipher.final("base64");
// Now Base64 is used to ENCODE the encrypted output, not to protect itCommon Use Cases for Base64
1. Email Attachments (MIME)
The SMTP protocol was designed for 7-bit ASCII text. Binary files (images, PDFs, archives) must be Base64-encoded before being included in email bodies. The MIME standard (RFC 2045) specifies Base64 as a Content-Transfer-Encoding method. Every email attachment you send goes through this process.
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="boundary123"
--boundary123
Content-Type: text/plain
Hello, please find the attachment.
--boundary123
Content-Type: image/png
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="logo.png"
iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAA
DUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==
--boundary123--2. JWT Tokens
JSON Web Tokens use Base64URL encoding for the header and payload segments. The three-part structure <code>header.payload.signature</code> encodes JSON data in a URL-safe format suitable for HTTP headers and query parameters.
3. CSS Data URIs
Small images, fonts, and icons can be embedded directly in CSS files as Base64 data URIs. This eliminates HTTP requests for critical above-the-fold assets, improving perceived load time:
/* Critical CSS: embed small icons to avoid render-blocking requests */
.loading-spinner {
background-image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0i...);
animation: spin 1s linear infinite;
}
/* Favicon as data URI in HTML */
<link rel="icon" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0i..." />4. Kubernetes Secrets
Kubernetes stores secret values as Base64-encoded strings in YAML manifests. This is for safe YAML serialization of binary data, NOT for security. Always enable encryption at rest for Kubernetes secrets in production:
# Kubernetes Secret manifest
apiVersion: v1
kind: Secret
metadata:
name: db-credentials
type: Opaque
data:
username: YWRtaW4= # echo -n "admin" | base64
password: cGFzc3dvcmQxMjM= # echo -n "password123" | base64
# Create from command line
kubectl create secret generic db-credentials \
--from-literal=username=admin \
--from-literal=password=password123
# Decode a secret
kubectl get secret db-credentials -o jsonpath="{.data.password}" | base64 -d5. API File Uploads
REST APIs that accept file uploads via JSON payloads use Base64 encoding to transmit binary file data within JSON strings. This is simpler than multipart uploads but adds 33% overhead.
6. WebSocket Binary Data
When transmitting binary data over WebSocket text frames, Base64 encoding ensures the data survives the text-based transport without corruption.
Try our free Base64 Encoder/Decoder tool β
Frequently Asked Questions
What is Base64 encoding used for?
Base64 encoding converts binary data to text so it can be safely transmitted through text-only systems. Common uses include embedding images in HTML/CSS (data URIs), JWT tokens, HTTP Basic authentication, email attachments (MIME), Kubernetes secrets, and storing binary data in JSON payloads.
How do I encode a string to Base64 in JavaScript?
In the browser, use btoa() to encode and atob() to decode ASCII strings. For Unicode, use TextEncoder: btoa(String.fromCharCode(...new TextEncoder().encode(str))). In Node.js, use Buffer.from(str).toString("base64") to encode and Buffer.from(b64, "base64").toString() to decode.
Is Base64 encoding secure? Can I use it to protect data?
No. Base64 is an encoding scheme, NOT encryption. Anyone can decode Base64 data instantly without a key. It provides zero security. For data protection, use proper encryption (AES-256, RSA) and always transmit sensitive data over HTTPS.
Why does Base64 increase the size of data by 33%?
Base64 represents every 3 bytes of input as 4 characters of output. Since 4/3 = 1.333, the encoded data is approximately 33% larger than the original. This is the trade-off for converting binary data into a text-safe format. Padding characters (=) may add a few extra bytes.
What is the difference between Base64 and Base64URL encoding?
Standard Base64 uses + and / characters which have special meaning in URLs. Base64URL (RFC 4648 Section 5) replaces + with - (hyphen) and / with _ (underscore), and typically omits padding (=). Base64URL is used in JWT tokens, URL query parameters, and filenames.
How do I convert an image to Base64 for use in HTML or CSS?
On the command line: base64 -w 0 image.png (Linux) or base64 image.png (macOS). In JavaScript browser: use FileReader.readAsDataURL(file). In Node.js: fs.readFileSync("image.png").toString("base64"). Then use the result in an img src attribute as data:image/png;base64,YOUR_STRING or in CSS as url(data:image/png;base64,YOUR_STRING). Only use this for small images under 5KB.
Can I use Base64 encoding on the command line?
Yes. On Linux use: echo -n "text" | base64 to encode and echo "dGV4dA==" | base64 -d to decode. On macOS the decode flag is -D (uppercase). OpenSSL works cross-platform: echo -n "text" | openssl base64. Windows PowerShell uses [Convert]::ToBase64String() and [Convert]::FromBase64String().
Conclusion
Base64 encoding is a foundational tool in every developerβs toolkit. It bridges binary and text worlds, enabling data URIs, JWT tokens, API authentication, email attachments, and much more. Remember the key rules: it adds ~33% size overhead, it is NOT encryption, and for files over 5KB you should prefer binary transfer. For quick encoding and decoding tasks, use our free online tool.