Developer Works offline

Base64 Encoder / Decoder

Convert text or a whole file to and from Base64 — handling UTF-8 and emoji correctly, with a URL-safe option, byte-size readouts, a data-URL preview and copy or download buttons.

Or encode a file
Drop a file here …or press Enter to choose one. Read locally as an ArrayBuffer — nothing is uploaded.

Choose any file — an image, a PDF, a small archive. It is read in your browser and never leaves the page.

Input size
—
Result length
—
Output
—
Ready — type or paste text, or choose a file.
Everything runs locally. Encoding and decoding are the public Base64 algorithms — they hide nothing, so never treat the output as a secret.

How Base64 encoding works

Base64 exists to move binary data through channels that only tolerate text: JSON fields, XML documents, email bodies, HTTP headers and data URLs. The algorithm takes the raw bytes, groups them into sets of three, and rewrites each 24-bit group as four 6-bit numbers. A 6-bit number has 64 possible values, so each one maps to a single printable character — the 62 letters and digits A–Z, a–z and 0–9, plus + and /.

That three-bytes-to-four-characters ratio is the whole trick, and it is also the whole cost: the encoded text is roughly 33% larger than the source. If the input length is not a multiple of three, the final group is short and is padded with = characters so the length always lands on a multiple of four. Those = signs carry no data — they are a checksum-free way of telling a decoder how many bytes the last group really contains.

The subtle part in a browser is text. JavaScript strings are sequences of UTF-16 code units, and the legacy btoa() function rejects anything above U+00FF with an InvalidCharacterError. So btoa("café") and any string containing an emoji both throw. The correct route, and the one this tool takes, is to turn the text into UTF-8 bytes first with new TextEncoder().encode(text), Base64-encode those bytes, and on the way back decode to bytes and run them through new TextDecoder().decode(bytes). That round-trip is lossless for every character the Unicode standard defines, accents and emoji included.

Input UTF-8 bytes Standard Base64 URL-safe Base64
Man 3 TWFu TWFu
Ma 2 TWE= TWE
café 5 Y2Fmw6k= Y2Fmw6k
~? 2 fj8= fj8

Accuracy, limits and honest caveats

Base64 is a bijection over byte strings, so for well-formed input the round-trip here is exact. The honest limitations are about ill-formed input, and about what Base64 is not for.

  • Invalid input is reported, never guessed. If the string contains characters outside the Base64 alphabet, or its length is impossible once padding is considered, the tool says so instead of returning empty output. It deliberately does not invent characters to force a decode.
  • Padding and whitespace are tolerated. Missing = at the end is fine — it is re-added automatically, because the length already tells the decoder what is missing. Line breaks from MIME-encoded data are stripped too, which matters for Base64 copied out of email.
  • Bytes are not always text. Decoding a Base64 string that really contains an image or a compressed archive produces replacement characters, because those bytes were never valid UTF-8. Nothing is lost — the file input pane is the right way to look at binary data — but the text pane will look like noise.
  • Base64 is not compression and not security. It adds about a third to the size, and it protects nothing: it is a public, keyless transform. Treating Base64 as obfuscation is a common and costly mistake.
  • Large files stay in memory. Everything happens on the main thread, so a multi-megabyte file will pause the page briefly while the string is built. For very large payloads a chunked streaming encoder is a better fit than a single-page tool.

A Data URL is Base64 plus a media type, for example data:image/png;base64,iVBORw0…. It is perfect for small inline icons, but the browser cannot cache it separately and it inflates the HTML, so keep it for payloads of a few kilobytes.

How to use this tool

  1. Encode text. Type or paste into the left pane — the output updates as you type, so there is no need to press anything. Accents and emoji are handled through UTF-8 and never throw.
  2. Decode a string. Paste the Base64 into the same left pane and press Decode. Both alphabets are accepted: a value containing - or _ is read as URL-safe automatically, and missing padding is repaired.
  3. Switch to the URL-safe alphabet. Tick the box before encoding when the result will travel inside a URL, a filename or a JWT-style token. The encoded string updates immediately, with + and / replaced and the padding removed.
  4. Encode a file. Drop a file onto the dashed area, or press Enter there to pick one. It is read as an ArrayBuffer and converted to Base64, and the readouts show the original byte size next to the encoded character count.
  5. Preview images. When the file is an image, a data-URL preview appears so you can confirm you encoded the file you meant. The browser renders the preview itself; nothing is uploaded.
  6. Take the result away. Copy result puts the string on the clipboard and Download result as .txt saves it to a file, ready to paste into a config value, an API payload or an img tag.

Because the page is a single static document with no network calls, it keeps working on a plane, on a locked-down machine, or anywhere an online encoder would be a bad idea for the data you are handling.

Frequently asked questions

Is Base64 encryption?

No. Base64 is a reversible transport encoding, not encryption. Anyone who has the string can decode it with the same public algorithm, so it hides nothing. If you need confidentiality, encrypt the data first with a real cipher and keep the key secret — Base64 only makes binary bytes safe to paste into text-only channels.

Why does btoa() fail on accented or emoji text?

btoa() was defined for binary strings and throws an InvalidCharacterError on any code unit above U+00FF, so "café" or a single emoji breaks the naive call. The fix, used here, is to convert the text to UTF-8 bytes with new TextEncoder().encode(text) first and then Base64-encode those bytes; decoding reverses the process with new TextDecoder().decode(bytes).

What is the URL-safe alphabet and why drop the padding?

Standard Base64 uses "+" and "/", which have reserved meanings inside a URL path or query string, so the URL-safe variant defined in RFC 4648 section 5 substitutes "-" and "_" and commonly strips the trailing "=" characters. This tool accepts either alphabet on input and re-adds padding automatically when you decode, so mismatched padding is never a hard failure.

How much larger is Base64 than the original data?

Base64 packs three bytes into four characters, so the encoded text is about 33% larger than the source, plus a little more for line breaks or a Data URL header. A 300 KB image becomes roughly 400 KB of text. That overhead is why Base64 is for embedding and transport, not for storing large files.

Sources & further reading