If you've ever worked with APIs, sent files via JSON, or just tried to understand how JWT tokens work — you've definitely encountered Base64. It's one of those technologies that seems complex at first, but is actually very simple. Let's dive in!
Base64 is essentially a way to convert any binary data (images, files, audio) into plain text. Why is this needed? Because many systems and protocols only work with text. For example, HTTP headers, JSON, XML — they're all text-based. And Base64 allows you to embed anything into them.
What exactly is Base64 and why is it needed?
I remember the first time I encountered Base64 — it was when working with email newsletters. It turns out that all email attachments are encoded in Base64! Yes, those very images and PDF files we send via email are converted into long text strings and transmitted as plain text. On the recipient's side, they're converted back into files.
Here are the main places where you'll definitely encounter Base64 in your work:
- Data URLs in HTML/CSS — when you embed an image directly into code, without a separate file. This is convenient for small icons.
- Email attachments (MIME) — everything you send via email is encoded in Base64.
- JWT tokens — those authentication tokens for APIs. They consist of three parts, and each part is Base64.
- Basic authentication — when you see the
Authorization: Basic ...header, that's also Base64. - File transfer via JSON — if you need to send a file through a REST API, you can encode it in Base64 and pass it as a string.
- Database storage — when you need to save binary data in a text field.
Important to remember: Base64 is encoding, not encryption. It doesn't make data secure. If you need to protect data — use encryption, such as AES. Base64 simply converts the format, and anyone can decode it back.
How it actually works
Let's understand the mechanics. I know that many developers use Base64 without thinking about how it works. But once you understand the principle — everything becomes obvious.
Base64 takes 3 bytes of data (that's 24 bits) and converts them into 4 characters. Why 3 bytes? Because 24 bits divide perfectly into 4 groups of 6 bits. And each character in Base64 represents 6 bits of information. So, 3 bytes → 4 characters.
The Base64 alphabet consists of 64 characters:
A-Z— 26 charactersa-z— another 26 characters0-9— 10 characters+and/— 2 characters=— used for padding when data is insufficient
That's 64 characters total — hence the name.
Let's look at the example of the word "Man"
The letter "M" in binary — 01001101.
The letter "a" — 01100001.
The letter "n" — 01101110.
Combine: 01001101 01100001 01101110.
Split into groups of 6 bits:
010011 (19) → character T
010110 (22) → character W
000101 (5) → character F
101110 (46) → character u
So "Man" becomes "TWFu".
Pretty simple, right? Now you understand that Base64 is just a lookup table between numbers and characters.
Base64 in different languages — real-world examples
When I first started programming, the biggest revelation for me was that every language has built-in functions for working with Base64. You don't need to write your own implementation — it's all ready to go.
JavaScript (Node.js)
In Node.js, it's simple — use Buffer:
// Encoding
const text = 'Hello, World!';
const encoded = Buffer.from(text, 'utf8').toString('base64');
console.log(encoded); // SGVsbG8sIFdvcmxkIQ==
// Decoding
const decoded = Buffer.from(encoded, 'base64').toString('utf8');
console.log(decoded); // Hello, World!
JavaScript (Browser)
In the browser, there's btoa and atob, but they only work with Latin characters. For Unicode, you need a small workaround:
function utf8ToBase64(str) {
return btoa(unescape(encodeURIComponent(str)));
}
function base64ToUtf8(str) {
return decodeURIComponent(escape(atob(str)));
}
// Usage
const encoded = utf8ToBase64('Hello, World!');
console.log(encoded); // SGVsbG8sIFdvcmxkIQ==
Python
In Python — the base64 module:
import base64
text = "Hello, World!"
encoded = base64.b64encode(text.encode('utf-8')).decode('utf-8')
print(encoded) # SGVsbG8sIFdvcmxkIQ==
decoded = base64.b64decode(encoded).decode('utf-8')
print(decoded) # Hello, World!
PHP
In PHP — two simple functions:
$text = "Hello, World!";
$encoded = base64_encode($text);
echo $encoded; // SGVsbG8sIFdvcmxkIQ==
$decoded = base64_decode($encoded);
echo $decoded; // Hello, World!
Java
In Java starting from version 8, there's a built-in Base64:
import java.util.Base64;
String text = "Hello, World!";
String encoded = Base64.getEncoder()
.encodeToString(text.getBytes("UTF-8"));
System.out.println(encoded);
byte[] decodedBytes = Base64.getDecoder().decode(encoded);
String decoded = new String(decodedBytes, "UTF-8");
System.out.println(decoded);
Go
In Go — the encoding/base64 package:
package main
import (
"encoding/base64"
"fmt"
)
func main() {
text := "Hello, World!"
encoded := base64.StdEncoding.EncodeToString([]byte(text))
fmt.Println(encoded)
decoded, _ := base64.StdEncoding.DecodeString(encoded)
fmt.Println(string(decoded))
}
Base64 vs Base64URL — what's the difference?
One time, I spent an entire hour trying to figure out why my JWT token wasn't working in a URL. It turned out that standard Base64 uses + and / characters, which have special meaning in URLs. To solve this, Base64URL was created.
The difference is simple:
+is replaced with-/is replaced with_=(padding) is removed
Now your token can be safely transmitted in a URL.
Base64URL functions in JavaScript
function base64UrlEncode(str) {
return btoa(str)
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, '');
}
function base64UrlDecode(str) {
str = str.replace(/-/g, '+').replace(/_/g, '/');
while (str.length % 4) {
str += '=';
}
return atob(str);
}
Base64 vs Hex — which is better?
I often see this question on forums. Hex (hexadecimal) can also encode data, but it's inefficient — each byte becomes 2 characters. Base64, on the other hand, converts 3 bytes into 4 characters.
| Format | Size Increase | Example | Use Cases |
|---|---|---|---|
| Base64 | ~33% | SGVsbG8= |
Email, JWT, API |
| Hex | 100% | 48656C6C6F |
Debugging, colors, hashes |
| Binary | 0% | 01001000... |
Storage, systems |
As you can see, Base64 is significantly more efficient than Hex. So for data transmission, always choose Base64.
Performance — what you need to know
There's one nuance I learned from experience. When I embedded a large image (about 2 MB) in HTML via a Data URL, the page loaded very slowly. It turns out, Base64 adds +33% to file size, and browsers don't cache Data URLs as efficiently as regular images.
- Size increase: ~33% — that's a lot for large files
- Caching: Data URLs aren't cached as separate files
- Recommendation: For files under 10 KB, Data URLs work well; for larger files, use separate files
How I use Base64 in real projects
1. Embedding a small icon in HTML
<img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cD..." alt="Icon" />
2. CSS sprites for fast loading
.icon-user {
background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cD...');
}
3. API authentication
// Authorization header
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
4. Sending files via JSON
{
"name": "report.pdf",
"content": "JVBERi0xLjQKMSAwIG9iago8PAovVHlwZSAvQ2F0YWxvZwovUGFnZXMgMiAwIFI..."
}
- Base64 converts binary data to text for transmission over text-based protocols.
- Increases data size by ~33%, but is more efficient than Hex.
- Used in JWT, email, Data URLs, Basic Authentication.
- Base64URL is a URL-safe version (replaces + and /).
- This is encoding, not encryption — don't use it for data protection.
Frequently Asked Questions
What is Base64 and why is it needed?
It's a way to convert any binary data into text. Needed for transmitting data over text-based protocols (HTTP, email, JSON).
Is Base64 secure?
No. It's encoding, not encryption. Anyone can decode your data. If you need to protect data — use encryption.
How much does data size increase?
Approximately 33%. A 100 KB file becomes 133 KB.
What is Base64URL?
A version of Base64 that's safe for URLs. Replaces + with -, / with _, and removes =.
How to decode Base64 in the browser?
Use atob(encoded). For Unicode — use decodeURIComponent(escape(atob(encoded))).
In conclusion
Base64 is a simple but very useful tool. I use it almost every day: for API debugging, for embedding icons, for working with JWT tokens. I hope this guide helps you understand and start using Base64 in your projects.
By the way, we have a Base64 online converter — you can try encoding and decoding text right now. It's free and works in the browser.