Developer ToolsWeb

What Is Base64, Really?

How binary becomes text, why it costs a third more, and when a data URL is the right call — or the wrong one.

The problem Base64 solves

A lot of the internet's plumbing was designed to carry text, not arbitrary bytes. Email bodies, JSON fields, URLs, XML, and many config formats expect printable characters and choke on raw binary — a byte that happens to be a control character or a quote can break the whole message. But we constantly need to send binary things through those text channels: an image in an email, a file in a JSON API, a small icon embedded in a stylesheet. Base64 is the bridge. It re-expresses any binary data using only 64 safe characters (A–Z, a–z, 0–9, and + and /), so it survives any text-only pipe. Convert anything both ways in theBase64 tool.

How it works

The trick is regrouping bits. Normal bytes are 8 bits each. Base64 takes the raw bits and re-slices them into groups of 6 bits, because 6 bits have exactly 64 possible values — one for each character in the alphabet. So every 3 bytes (24 bits) become 4 Base64 characters (4 × 6 = 24 bits). When the data does not divide evenly into three, the encoder pads the end with one or two = signs, which is why Base64 strings so often end in = or ==.

That 3-to-4 ratio is the whole story of Base64's famous size overhead: four characters for every three bytes means the encoded form is about 33% larger than the original. Base64 is emphatically not compression — it trades size for compatibility. Understanding this is the key to using it well: it is a transport format, not a storage one.

Data URLs: files inside your HTML

The most visible use of Base64 on the web is the data URL. Instead of pointing an image at a separate file, you embed the whole thing inline:

<img src="data:image/png;base64,iVBORw0KGgoAAAANS…">

The browser reads the Base64, reconstructs the image, and shows it — no extra network request. The same works in CSS (background: url(data:image/svg+xml;base64,…)) and anywhere a URL is accepted. The Base64 tool produces exactly this data URL when you drop in an image, ready to paste.

When to inline — and when not to

Data URLs are a genuine performance tool, but only for the right assets. Because they are baked into the HTML or CSS, they save a round-trip request, which helps for tiny, critical images (a small icon, a 1×1 spacer, an inline SVG). But that same inlining is a liability for anything larger:

Inline as data URLLink as a file
Tiny icons, inline SVGsPhotos and large images
Critical, above-the-fold assetsAnything reused across pages
Avoiding a request for 1–2 KBAssets that benefit from caching

The reasons not to inline larger files: the 33% bloat is added to your HTML/CSS on every page load, an inlined asset cannot be cached separately by the browser (it re-downloads with the page every time), and giant Base64 blobs make source hard to read. The rule of thumb: inline only small, critical assets; link everything else.

Where else Base64 shows up

Base64 vs Base64URL, and a Unicode note

You will sometimes see Base64URL, a variant that swaps the two unsafe characters + and / for - and _ and drops the padding, so the result is safe to drop straight into a URL or filename. It is the same idea with a URL-friendly alphabet — JWTs use it. One more subtlety worth knowing: Base64 encodes bytes, not characters, so encoding text correctly means first turning it into bytes with a character encoding like UTF-8. A good encoder does this for you, which is why emoji and accented letters round-trip cleanly through the Base64 tool.

The encoding, step by step

Working through one example makes the whole scheme obvious. Take the three characters Man. In ASCII these are the bytes 77, 97 and 110, which in binary are 01001101 01100001 01101110 — 24 bits in total.

Base64 ignores the byte boundaries and re-slices those same 24 bits into four groups of six: 010011 010110 000101 101110. Read as numbers, those groups are 19, 22, 5 and 46. Look each up in the Base64 alphabet (A–Z is 0–25, a–z is 26–51, 0–9 is 52–61, then + and /) and you get T, W, F, u — so Man encodes to TWFu. Three bytes in, four characters out, every time.

The padding rules follow directly from that. If your data does not divide evenly into groups of three bytes, the final group is short: two leftover bytes produce three characters plus one =, and one leftover byte produces two characters plus ==. That is why you can often guess the length of the original data from the tail of a Base64 string, and why an encoded string's length is always a multiple of four.

The variants you will meet

"Base64" is really a family. The core idea is identical in each; what changes is the last two characters of the alphabet and the treatment of padding, chosen to suit where the data will travel.

VariantLast two charsUsed for
Standard+ /General data, MIME, data URLs
Base64URL- _URLs, filenames, JWTs
MIME (email)+ /Wrapped at 76 characters per line

The URL-safe variant exists because + and / both have special meaning in a URL — a + can be read as a space in query strings and / is a path separator — so leaving them in would corrupt the value. If you ever decode a string and get gibberish, checking whether it is actually the URL-safe variant (and swapping the characters back) is a good first move.

Unicode: the bug everyone hits

Here is the single most common Base64 mistake in JavaScript. The built-in btoa() function operates on characters with codes 0–255, not on Unicode text. Feed it an emoji or an accented character and it throws an "InvalidCharacterError", because those characters live outside that range.

The fix is to convert your text to bytes first using UTF-8, then Base64-encode those bytes — which is exactly what a TextEncoder does, and exactly what this tool does internally. That is why "Hello 👋 café" round-trips correctly here while a naive btoa() call fails on it. The general principle is worth remembering beyond JavaScript: Base64 encodes bytes, not characters, so text must always be turned into bytes by a defined character encoding first. Mismatched encodings on the two ends are the usual cause of accented letters arriving mangled.

Performance: the real cost of inlining

The 33% size increase is the headline cost, but for web pages it is not the most important one. The bigger issue is caching. A linked image is fetched once and then cached by the browser, so subsequent pages load it for free. An inlined data URL is part of the HTML or CSS, so it is re-downloaded with every page that includes it and can never be cached separately.

There is also a rendering cost: large Base64 blobs in a stylesheet delay that stylesheet's parsing, and CSS is render-blocking, so a heavy inlined image can push back the moment your page first paints. And on the encoding side, generating Base64 for a very large file consumes memory proportional to the file, which matters on mobile devices. The practical guidance that falls out of all this is consistent: inline only small assets — a few kilobytes at most — where saving a request genuinely matters, and link everything else so the browser's cache can do its job.

Base64 is not security

This deserves stating plainly because it causes real breaches: Base64 provides no protection whatsoever. It is a public, reversible transformation with no key — anyone can decode it instantly, as this tool demonstrates. Yet Base64-encoded values are routinely mistaken for encrypted ones because they look like random characters.

The most common example is HTTP Basic authentication, where username:password is Base64-encoded into the Authorization header. That encoding does nothing to hide the credentials; it exists only to make them safe to transmit as header text. Basic auth is acceptable only over HTTPS, where TLS provides the actual confidentiality. The same logic applies anywhere you see Base64: if the data genuinely needs protecting, it must be encrypted (or hashed, for passwords) — and if you need that, reach for a proper cryptographic tool rather than an encoder.

Decoding failures and what they mean

When a decode fails or produces nonsense, the cause is almost always one of a small handful of things. Recognising the symptom saves a lot of guessing.

SymptomLikely cause
"Invalid character" errorURL-safe variant (-/_) fed to a standard decoder
Length not a multiple of 4Padding stripped, or the string was truncated
Accents/emoji come out garbledCharacter-encoding mismatch (not UTF-8 on both ends)
Decodes but is still unreadableIt was binary, not text — try decoding to a file
Fails when copied from an emailLine breaks inserted at 76 characters; strip whitespace

The last one catches people surprisingly often. MIME wraps Base64 at fixed line lengths, so a value copied out of a raw email or certificate file arrives full of newlines. Stripping all whitespace before decoding fixes it — which is exactly what this tool does automatically, along with tolerating missing padding.

A note on very large files

Encoding a large file in a browser is memory-hungry: the raw bytes, the Base64 string, and any intermediate copies all sit in memory at once, so a 50 MB file can briefly need several hundred megabytes. On a phone that is enough to crash a tab. For anything beyond a few megabytes, prefer uploading the raw file rather than a Base64 representation, or process it in chunks. Base64 was designed for small payloads travelling through text channels, and it remains happiest there — a fact worth remembering before you encode a video into a JSON field.

Relatives worth knowing

Base64 is not the only encoding of its kind, and knowing the alternatives helps you pick the right one. Hexadecimal (Base16) represents each byte as two characters — simpler to read and debug, and the standard for hashes and colour codes, but it doubles the size rather than adding a third. Base32 uses a smaller alphabet with no case sensitivity and no easily-confused characters, which is why it appears in TOTP two-factor secrets and recovery codes that humans have to type or read aloud.

There is also Base85 (used in PostScript and PDF), which squeezes four bytes into five characters for only about 25% overhead — more efficient than Base64, but with a larger alphabet that includes characters unsafe in many contexts. The pattern across all of them is a straightforward trade: the more characters your alphabet uses, the less overhead you pay, but the fewer places the result is safe to put. Base64 sits at the practical sweet spot for the web, which is why it won.

In short: Base64 is a transport format, not a storage or security one. Use it when binary data must travel through a text-only channel, keep the payloads small, always be explicit about the character encoding on both ends, and never mistake it for protection. Base64 is one of those quiet workhorses you use constantly without noticing — every inline icon, every token, every file tucked into JSON. Now you know what it is doing and what it costs. Try encoding a snippet, an image, or a file both ways in theBase64 tool— all of it computed privately in your browser.