Base64, Base64URL, and Data URIs

What Base64 encoding is for, why it makes data 33% bigger, how the URL-safe variant differs, and where Data URIs fit in.

What Base64 is (and is not)

Base64 encodes arbitrary binary data using 64 safe ASCII characters — A–Z, a–z, 0–9, plus + and / — so it can travel through channels that only tolerate text: JSON bodies, email, XML, HTTP headers, environment variables. It is an encoding, not encryption: anyone can decode it instantly, and it provides zero confidentiality.

The cost is size. Base64 works in 3-byte groups mapped to 4 characters, so output is about 33% larger than the input, plus padding. Sending a 10 MB file through Base64 means shipping ~13.3 MB.

Padding and the = signs

Because input rarely divides neatly into 3-byte groups, the output is padded with = to a multiple of four characters. One leftover input byte produces xx==, two leftover bytes produce xxx=. This is why Base64 strings end with zero, one, or two equals signs — never three.

Padding is decorative for most decoders, which is why URL-safe contexts often strip it. Some strict parsers require it, though, so a decoder that accepts both is the practical choice.

Base64URL: the web-safe variant

Standard Base64's + and / characters break URLs (+ means space in query strings; / splits paths). RFC 4648 defines Base64URL, which swaps + for - and / for _, and typically omits padding. This is the variant used inside JSON Web Tokens — the three dot-separated segments of a JWT are each Base64URL-encoded JSON — and in URL-safe identifiers.

If decoding fails with 'invalid character' on input containing - or _, you are holding Base64URL and the decoder expects standard Base64, or vice versa.

Data URIs

A Data URI inlines a resource directly in HTML or CSS: data:image/png;base64,iVBOR.... The part before the comma declares the MIME type and that the payload is Base64. This eliminates an HTTP request for small assets — favicons, tiny icons, inline SVG fallbacks — at the price of the 33% size tax and no separate caching.

Practical rule of thumb: Data URIs make sense for assets under a couple of kilobytes. Beyond that, a cacheable file with a content-hashed name wins on every metric.

UTF-8 comes first

Base64 encodes bytes, not characters. Encoding a string with non-ASCII text (accented characters, emoji, CJK) without specifying UTF-8 produces garbage on the other side — this is the bug behind atob() mangling international text in browsers. The correct pipeline is: string → UTF-8 bytes → Base64, and decode in reverse.

References

Related tools