Base64 Encoding Explained: When to Use It and When Not To

Base64 is one of those encoding schemes that developers use constantly without fully understanding what it does β€” or more importantly, what it does not do.

What Is Base64?

Base64 encodes binary data into ASCII text using a 64-character alphabet (A–Z, a–z, 0–9, +, /) plus = for padding. Every 3 bytes of binary data become 4 ASCII characters β€” a 33% size increase.

Input:  Man (3 bytes: 0x4D 0x61 0x6E)
Output: TWFu (4 chars)

Why Does It Exist?

Base64 was invented to safely transmit binary data through systems designed for text β€” specifically email (SMTP), which was ASCII-only. Today it remains useful wherever you need to embed binary data in text-only contexts.

Common Use Cases

Data URLs in HTML/CSS

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

Embeds images directly in HTML, eliminating an HTTP request. Useful for small icons in critical-path CSS.

JWT Tokens

The header and payload of a JWT are Base64URL-encoded (a variant that replaces + with - and / with _ for URL safety, and omits padding).

HTTP Basic Authentication

Authorization: Basic dXNlcjpwYXNzd29yZA==

This is user:password in Base64. It is not encrypted β€” anyone who intercepts this header can decode it instantly. Always use HTTPS.

Embedding Certificates and Keys in PEM Format

PEM files (.pem, .crt, .key) are DER binary data wrapped in Base64 with -----BEGIN ...----- / -----END ...----- headers.

Base64 Is NOT Encryption

This bears repeating. Base64 provides zero security. It is trivially reversible. Do not:

  • Store passwords in Base64
  • Send sensitive data in Base64 thinking it is "encoded"
  • Use Base64 as obfuscation in security-sensitive code
// Anyone can do this:
atob('dXNlcjpwYXNzd29yZA==') // β†’ "user:password"

Base64 vs Base64URL

Standard Base64 uses + and / which are special characters in URLs. Base64URL substitutes:

StandardURL-safe
+-
/_
= (padding)omitted

Use Base64URL for anything in a URL, query string, or JWT.

Encoding in JavaScript

// Encode
const encoded = btoa('Hello, World!');        // SGVsbG8sIFdvcmxkIQ==

// Decode
const decoded = atob('SGVsbG8sIFdvcmxkIQ=='); // Hello, World!

// For binary data / files, use FileReader or Buffer (Node.js)
Buffer.from('Hello').toString('base64');       // SGVsbG8=
Buffer.from('SGVsbG8=', 'base64').toString();  // Hello

Size Considerations

Base64 inflates data by ~33%. For large files or high-traffic endpoints, this matters:

  • A 1 MB image becomes ~1.37 MB as a data URL
  • On high-traffic APIs, always serve binary as binary

Use Base64 for small payloads (icons, thumbnails, short tokens) and direct binary transfer for everything else.