artisan.dev

Base64 Encoding Explained: How It Works and When to Use It

By Tahsin Abrar · Updated

Base64 shows up everywhere in web development: data URIs, email attachments, HTTP Basic authentication, JSON Web Tokens, and binary values stored in JSON. It is a way to represent arbitrary bytes using only 64 "safe" printable characters, so binary data can travel through systems designed for text.

This guide explains the mechanics with a worked example, the URL-safe variant, and the Unicode trap in JavaScript's btoa(). Try the examples in the Base64 Encoder / Decoder.

Try itOpen the Base64 Encoder / Decoder — runs in your browser

How the encoding works

Base64 reads the input three bytes (24 bits) at a time and splits those 24 bits into four groups of 6 bits. Each 6-bit value (0–63) is mapped to one character of the alphabet A–Z, a–z, 0–9, + and /. Here is the word Man:

StepMan
ASCII byte7797110
Bits010011010110000101101110
24 bits:   010011 010110 000101 101110
6-bit:       19     22      5     46
Base64:       T      W      F      u     →  "TWFu"

Because every 3 input bytes become 4 output characters, Base64 output is about 33% larger than the input (plus line breaks, if the variant uses them). A 3 MB image becomes roughly 4 MB of Base64 text.

What the = padding means

When the input length is not a multiple of three, the last group is short. The encoder pads it with zero bits and appends = characters so the output length stays a multiple of four:

  • 1 leftover byte → 2 Base64 characters + == (e.g. M → TQ==)
  • 2 leftover bytes → 3 Base64 characters + = (e.g. Ma → TWE=)
  • 0 leftover bytes → no padding (e.g. Man → TWFu)

Padding carries no data. Many decoders accept input without it, and some formats (JWTs, for example) always omit it.

Base64 vs Base64URL

Standard Base64 uses + and /, which have special meanings in URLs and file names. RFC 4648 defines a URL- and filename-safe alphabet that swaps them:

VariantIndex 62Index 63PaddingUsed in
Base64+/Required =MIME email, data URIs, PEM keys, Basic auth
Base64URL-_Usually omittedJWTs, URL parameters, file names

Mixing them up is a frequent bug: decoding a JWT segment with a standard Base64 decoder fails as soon as it contains - or _. Convert by replacing - with +, _ with /, and re-adding = until the length is a multiple of 4.

Base64 in JavaScript — and the Unicode trap

Browsers provide btoa() (binary to ASCII) and atob(). They operate on "binary strings" where each character is one byte, so any character above U+00FF throws:

btoa("café ☕");
// ✗ InvalidCharacterError: string contains characters outside of the Latin1 range

Encode the text to UTF-8 bytes first, then Base64 those bytes:

function toBase64(text) {
  const bytes = new TextEncoder().encode(text);
  let bin = "";
  for (const b of bytes) bin += String.fromCharCode(b);
  return btoa(bin);
}

function fromBase64(b64) {
  const bin = atob(b64);
  const bytes = Uint8Array.from(bin, (c) => c.charCodeAt(0));
  return new TextDecoder().decode(bytes);
}

toBase64("café ☕"); // "Y2Fmw6kg4piV"

In Node.js, use Buffer.from(text, "utf8").toString("base64") and Buffer.from(b64, "base64").toString("utf8"); "base64url" is also supported as an encoding name. Recent browsers additionally ship Uint8Array.prototype.toBase64() and Uint8Array.fromBase64(), which handle both alphabets directly. The encoder on this site is Unicode-safe.

When to use Base64 — and when not to

Good uses

  • Embedding small binary data in text formats: JSON fields, XML, YAML, environment variables.
  • Data URIs for tiny images or fonts, e.g. data:image/png;base64,iVBORw0….
  • HTTP Basic authentication, where user:password is Base64-encoded in the Authorization header — always over HTTPS, since anyone can decode it.
  • Binary-safe transport through systems that may mangle raw bytes, such as email (MIME).

Poor uses

  • Hiding secrets. Base64 is an encoding, not encryption; decoding requires no key. Use real encryption, or a hash when you only need to compare values.
  • Large files in JSON or HTML. The 33% overhead and loss of streaming add up. Upload binary data as multipart/form-data or serve it as a separate file.
  • Big inline images. Data URIs can't be cached separately from the page that contains them; keep them to small icons.

FAQ

Is Base64 encryption?
No. Base64 is a reversible encoding with a public alphabet — anyone can decode it without a key. It provides no confidentiality at all.
Why does my Base64 string end with == ?
The = characters are padding. They appear when the input length isn't a multiple of 3 bytes: one leftover byte gives ==, two leftover bytes give =.
How much bigger is Base64 than the original?
About 33%: every 3 bytes become 4 characters. The exact length is 4 × ceil(n / 3) characters for n input bytes, before any line breaks.

More guides