Also available in: Español · Português · Français · العربية
Base64 Encoder & Decoder
Encode text to Base64 or decode Base64 back to text — correctly, with full UTF-8 support, entirely in your browser.
What is a base64 encoder and decoder?
Base64 turns arbitrary bytes into a string built from 64 printable characters — A–Z, a–z, 0–9, and two more — which is the whole point: a lot of channels that carry data around (email, JSON fields, URLs, HTTP headers, config files) only reliably handle text, not raw bytes. Encoding maps those bytes onto safe characters; decoding reverses it, byte for byte.
This tool does both directions. Paste into the input and get the other representation instantly, in Standard or URL-safe alphabet, with or without line breaks, computed locally as you type — nothing is sent anywhere to do it.
How to use it
- Pick Encode or Decode, then an alphabet. Click the Mode pill for the direction you want, then choose Standard (+ / =) or URL-safe (- _) under Alphabet — URL-safe is what JWTs and URL-embedded values use; Standard is the default everywhere else.
- Paste your text or your Base64 into the input. The output box below updates on every keystroke. In Encode mode, tick Break lines every 76 characters if you need old-school MIME-wrapped output; otherwise leave it off.
- Copy the result and sanity-check the counts. Press Copy — it switches to Copied! for two seconds — then glance at the counts row: Characters in, Bytes in, Characters out. If bytes in and characters in don't match, you already know your text wasn't plain ASCII.
Why not just btoa()?
The one-line shortcut everyone reaches for — the browser's built-in btoa() — is broken for anything outside plain ASCII, and it breaks in two different ways depending on which character trips it. For a character in the Latin-1 range, it fails silently, which is worse than crashing: btoa("café") returns Y2Fm6Q==, not the correct Y2Fmw6k=. It encoded the é as the single byte e9 instead of the two bytes UTF-8 actually requires, c3 a9. Feed Y2Fm6Q== to any decoder expecting UTF-8 and you get "caf" followed by a replacement character — no exception, no warning, anywhere in the chain.
For anything above U+00FF, btoa() gives up entirely: btoa("👍"), btoa("€") and btoa("日本語") all throw InvalidCharacterError. This tool sidesteps both failure modes by converting text to UTF-8 bytes first and encoding those bytes, so everything round-trips: café (5 bytes) becomes Y2Fmw6k=; 👍 (4 bytes) becomes 8J+RjQ==; 日本語 (9 bytes) becomes 5pel5pys6Kqe; مرحبا (10 bytes) becomes 2YXYsdit2KjYpw==; the 🇧🇷 flag emoji (8 bytes) becomes 8J+Hp/Cfh7c=.
Base64 counts bytes, not characters, which is also why the counts row shows both separately. café is 4 characters but 5 bytes; 👍 is one character and 4 bytes, and even JavaScript's own .length reports 2 for it. The conversion itself is exactly 4/3 — every 3 input bytes become 4 output characters, padded up to a multiple of four with = — so the output is reliably about a third bigger: 100 bytes becomes 136 characters, 3,000 bytes becomes 4,000.
The alphabet choice matters too. Standard base64 uses + and / and pads with =; URL-safe swaps those for - and _ and usually drops the padding, because +, / and = all mean something else inside a URL or a filename. The same three bytes encode as +/++ in standard base64 and -_-- URL-safe — that's the variant JSON Web Tokens use, which is why Alphabet is its own control here instead of a single fixed output.
What this tool doesn't do
Base64 is an encoding, not encryption. It's trivially reversible by anyone who recognizes the alphabet — there's no key, no secret, nothing to crack. Never use it to hide something you actually care about; it exists to move bytes through channels that only accept text, not to protect them.
It's also a text tool, not a file converter. Decoding runs the resulting bytes through a strict UTF-8 decoder, so pasting the base64 of a PNG or a zip file will report that the bytes aren't valid text rather than show you an image or hand you a download.
Nothing is uploaded, which is the real reason to use a browser tool for anything sensitive — pasting a token or a customer's data into someone's server-side base64 encoder sends that data to their server, logs included. Whatever you paste here is gone the moment you reload the page; nothing is stored.
Why is it free?
Encoding and decoding Base64 is arithmetic your browser can already do in microseconds — there's no model to run and no server to pay for, so there's no reason to put it behind a login. It runs entirely client-side, same as everything else on FreeToGenerate.com: nothing to meter, nothing worth charging for.