Base64 is one of those things developers use constantly without fully understanding why. You see it in image embeds, JWTs, email attachments, and API responses. This guide explains what it actually is, how to use it in code, and when it's the wrong tool for the job.
What is Base64?
Base64 is an encoding scheme that converts binary data into a string of 64 printable ASCII characters: A–Z, a–z, 0–9, +, and /. The = character is used as padding.
It was designed to solve a specific problem: safely transmitting binary data through systems that only handle text. Email protocols (SMTP), XML, JSON, and HTML were all designed around text. If you try to embed a raw PNG file in a JSON field, the binary bytes will corrupt the text stream.
Base64 converts binary → ASCII text, making it safe to embed anywhere text is allowed.
How Base64 Encoding Works
Base64 takes every 3 bytes of input (24 bits) and splits them into four 6-bit groups. Each 6-bit group maps to one of the 64 characters in the Base64 alphabet.
Example: encoding the string Man
M a n
01001101 01100001 01101110 (3 bytes = 24 bits)
Split into four 6-bit groups:
010011 010110 000101 101110
19 22 5 46
T W F u
Result: TWFu
If the input isn't a multiple of 3 bytes, = padding characters are added.
Base64 in JavaScript
Modern browsers and Node.js (v16+) have built-in Base64 support:
// Encode
const encoded = btoa('Hello, World!')
console.log(encoded) // SGVsbG8sIFdvcmxkIQ==
// Decode
const decoded = atob('SGVsbG8sIFdvcmxkIQ==')
console.log(decoded) // Hello, World!
For binary data (files, ArrayBuffers) in the browser:
// File to Base64
function fileToBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.onload = () => resolve(reader.result)
reader.onerror = reject
reader.readAsDataURL(file)
})
}
const base64 = await fileToBase64(file)
// Returns: "data:image/png;base64,iVBORw0KGgo..."
In Node.js:
// Encode
const encoded = Buffer.from('Hello, World!').toString('base64')
console.log(encoded) // SGVsbG8sIFdvcmxkIQ==
// Decode
const decoded = Buffer.from('SGVsbG8sIFdvcmxkIQ==', 'base64').toString('utf8')
console.log(decoded) // Hello, World!
// Encode a file
const fs = require('fs')
const fileBuffer = fs.readFileSync('./image.png')
const base64File = fileBuffer.toString('base64')
Base64 in Python
import base64
# Encode a string
text = "Hello, World!"
encoded = base64.b64encode(text.encode('utf-8'))
print(encoded) # b'SGVsbG8sIFdvcmxkIQ=='
# Decode
decoded = base64.b64decode('SGVsbG8sIFdvcmxkIQ==').decode('utf-8')
print(decoded) # Hello, World!
# Encode a file
with open('image.png', 'rb') as f:
encoded_file = base64.b64encode(f.read()).decode('utf-8')
Base64 in the Terminal
# Encode
echo -n "Hello, World!" | base64
# SGVsbG8sIFdvcmxkIQ==
# Decode
echo "SGVsbG8sIFdvcmxkIQ==" | base64 --decode
# Hello, World!
# Encode a file
base64 image.png > image.b64
# Decode a file
base64 --decode image.b64 > image.png
On macOS, use base64 -D instead of base64 --decode.
Common Use Cases
Embedding images in HTML/CSS:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..." />
.icon {
background-image: url('data:image/svg+xml;base64,PHN2Zy...');
}
JSON Web Tokens (JWT):
JWTs use Base64URL (a variant that replaces + with - and / with _) to encode the header and payload sections.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0In0.abc
|--- header (Base64URL) ---|.|- payload -|.|- signature -|
API authentication:
HTTP Basic Auth encodes username:password in Base64:
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
Email attachments (MIME): The SMTP protocol uses Base64 to encode binary attachments so they can travel over text-based email infrastructure.
What Base64 is NOT
- Not encryption. Base64 is trivially reversible by anyone. Never use it to "hide" sensitive data.
- Not compression. Base64 output is ~33% larger than the input.
- Not hashing. Unlike SHA-256, it's fully reversible.
If you need to protect data, use encryption (AES, RSA) or hashing (bcrypt for passwords, SHA-256 for checksums).
URL-Safe Base64
Standard Base64 uses + and / which have special meaning in URLs. URL-safe Base64 replaces these:
+→-/→_
// URL-safe encode in Node.js
const urlSafe = Buffer.from(data).toString('base64')
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=/g, '') // padding often omitted in URLs
Try It Online
Use our free Base64 Encoder/Decoder to encode and decode instantly in your browser. Supports text and file input — no upload, everything runs locally.
Summary
- Base64 encodes binary data as ASCII text so it can travel through text-only systems
- It increases size by ~33% and is not encryption or compression
- Use
btoa()/atob()in browsers,Bufferin Node.js,base64module in Python - For URLs, use URL-safe Base64 (replace
+→-and/→_) - JWTs, data URIs, Basic Auth, and email attachments all use Base64
References & Credits
- RFC 4648 — The Base16, Base32, and Base64 Data Encodings — IETF, the official Base64 specification
- MDN Web Docs: btoa() — Mozilla Developer Network
- MDN Web Docs: atob() — Mozilla Developer Network
- Node.js Buffer documentation — Node.js official docs
- Python base64 module — Python official docs
- Introduction to JSON Web Tokens — Auth0 / jwt.io