What Is Base64 Encoding, and When Should You Use It?

How Base64 turns bytes into text, why encoded data grows by a third, how Base64Url differs, and why Base64 is never a way to hide or secure data.

· 3 min read

Base64 shows up everywhere: in data URLs, email attachments, JWTs, HTTP Basic auth and API payloads. It solves one specific problem, which is moving binary data through systems that only handle text safely. Here's how it works, what it costs, and the cases where it's the wrong tool.

How Base64 works

Base64 takes three bytes (24 bits) at a time and splits them into four groups of 6 bits. Each 6-bit value, from 0 to 63, maps to one character from a 64-character alphabet:

A–Z  →  0–25
a–z  →  26–51
0–9  →  52–61
+    →  62
/    →  63

Encoding the word Hi! goes like this:

StepValue
TextH i !
Bytes72 105 33
Bits01001000 01101001 00100001
6-bit groups010010 000110 100100 100001
Indexes18 6 36 33
Base64SGkh

Decoding runs the same steps backwards. You can try both directions in the Base64 encoder and decoder, which runs in your browser.

Why there's sometimes = at the end

Input doesn't always divide evenly into three-byte blocks. When one or two bytes are left over, the encoder pads the output with = so its length stays a multiple of four:

InputOutput
Hi! (3 bytes)SGkh
Hi (2 bytes)SGk=
H (1 byte)SA==

Some formats drop the padding because the decoder can work out the length on its own. If a strict decoder rejects a string, adding = until the length is a multiple of four usually fixes it.

Base64 makes data about 33% bigger

Every 3 bytes become 4 characters, so encoded data is roughly four thirds of the original size, plus a little padding. A 1 MB image becomes about 1.33 MB of Base64 text.

That's fine for small things like icons, keys or tokens. For large files it adds up: inlining big images as data URLs bloats your HTML and CSS, and those bytes can't be cached separately. Serve large files as files.

Base64 vs Base64Url

Standard Base64 uses + and /, which mean something in URLs and file names. Base64Url swaps them out:

Base64Base64Url
Character 62+-
Character 63/_
Padding= requiredUsually omitted
Used inEmail (MIME), data URLs, Basic authJWTs, URL parameters, file names

If you're decoding a JWT segment with a standard Base64 decoder, convert - to + and _ to / first. Our JWT decoding guide walks through that.

Encoding and decoding in code

JavaScript in the browser:

btoa('Hi!');   // "SGkh"
atob('SGkh');  // "Hi!"

btoa only accepts characters in the Latin-1 range, so it throws on emoji or most non-English text. Encode to UTF-8 bytes first:

const bytes = new TextEncoder().encode('héllo 👋');
const base64 = btoa(String.fromCharCode(...bytes));

Node.js:

Buffer.from('Hi!').toString('base64');      // "SGkh"
Buffer.from('SGkh', 'base64').toString();   // "Hi!"
Buffer.from('Hi!').toString('base64url');   // "SGkh"

Python:

import base64
base64.b64encode(b"Hi!")          # b'SGkh'
base64.urlsafe_b64encode(b"Hi!")  # Base64Url

Command line:

echo -n 'Hi!' | base64        # SGkh
echo 'SGkh' | base64 -d       # Hi!

The -n matters. Without it, echo adds a newline that gets encoded too, and you'll get SGkhCg== instead.

Base64 is not encryption

Base64 has no key. Anyone can decode it instantly, so it hides nothing. This trips people up most often with:

  • HTTP Basic auth. The Authorization: Basic dXNlcjpwYXNz header is just user:pass in Base64. Only HTTPS protects it.
  • Kubernetes Secrets. Values in a Secret manifest are Base64-encoded, not encrypted. Anyone who can read the manifest can read the secret.
  • "Obfuscated" config. Base64 in a config file stops nobody.

If data needs protecting, encrypt it. If you need to check that data wasn't changed, use a hash or a signature. Base64 only changes how data is represented.

When to use Base64

Good fits:

  • Embedding small binary data in JSON, XML or YAML, which can't carry raw bytes.
  • Small inline images or fonts as data URLs.
  • Email attachments, where MIME requires it.
  • Carrying binary tokens, keys and signatures in headers or URLs, using Base64Url.

Poor fits:

  • Large files, because of the 33% overhead.
  • Anything you're trying to keep secret.
  • Data that's already text. Just send the text.

Need to encode or decode something now? Use the Base64 tool.