← All articles · April 18, 2026 · fmt.hjlabs.in

Base64 Encoding Explained: Why It's Not Encryption

Base64 is so common in 2026 web development that few developers stop to understand what it actually does. Used incorrectly, it bloats payload sizes, breaks parsers, or — most embarrassingly — gets confused with encryption. Here is the complete primer.

What Base64 actually is

Base64 is a binary-to-text encoding that represents binary data using 64 ASCII characters: A-Z, a-z, 0-9, +, /. Every 3 bytes of binary become 4 characters of Base64. There's also = as a padding character.

The "64" comes from 2^6 = 64 — each Base64 character encodes 6 bits.

What Base64 is NOT

  1. Not encryption. Anyone can decode Base64 with a single command. Don't use it to "hide" passwords or API keys.
  2. Not compression. Base64 makes data 33% LARGER, not smaller.
  3. Not URL-safe by default. The + and / characters break URLs. Use Base64URL (replaces + with -, / with _) for URLs.
  4. Not a hash. It's reversible. A hash is one-way.

How encoding works (the mechanic)

Take 3 bytes (24 bits): "abc" = 01100001 01100010 01100011

Split into 4 groups of 6 bits: 011000 010110 001001 100011

Map each 6-bit group to a Base64 character: Y W J j

So "abc" in Base64 is "YWJj".

The padding (=) explained

If your input doesn't divide evenly into 3 bytes, you pad with zero-bits and signal the original length with =:

Some Base64 variants drop the padding entirely. JWT uses unpadded Base64URL.

The 33% size overhead

Every 3 bytes become 4 ASCII characters. For ASCII transport (JSON, email), that's a 33% size penalty. A 1MB image becomes ~1.33MB in Base64.

Plus: line wrapping in MIME Base64 adds ~1% more. PEM-encoded certificates wrap every 64 characters with newlines.

When Base64 is the right tool

When Base64 is the wrong tool

Base64URL — for URLs and JWTs

Standard Base64 uses + and /, which break URLs. Base64URL replaces them with - and _, and often drops padding.

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

Encode/decode in different languages

// JavaScript
btoa('hello')              // "aGVsbG8="
atob('aGVsbG8=')           // "hello"

// Node.js
Buffer.from('hello').toString('base64')
Buffer.from('aGVsbG8=', 'base64').toString()

# Python
import base64
base64.b64encode(b'hello')
base64.b64decode('aGVsbG8=')

// Go
base64.StdEncoding.EncodeToString([]byte("hello"))

btoa() / atob() Unicode trap

JavaScript's btoa only works on Latin-1. Pass it a string with emoji or non-ASCII and it throws. The fix:

// Modern (Node 18+, modern browsers)
const b64 = Buffer.from(text, 'utf8').toString('base64');

// Browser polyfill
btoa(unescape(encodeURIComponent(text)));

Tools

Bottom line

Base64 is a binary-to-text encoding with 33% overhead. Use it for embedding small binary in text-only formats (JSON, URLs, email). Don't use it to "hide" data, don't use it for large files, and don't confuse Base64 with Base64URL — the latter is what JWTs and most modern URL-safe encodings use.

Try the free dev tools suite

15+ tools. 100% client-side. No signup. No tracking.

Browse all tools →

More from the blog