Correct UTF-8 handling
Encodes through a proper UTF-8 byte conversion, so accented characters, CJK text and emoji round-trip instead of turning into mojibake — the classic atob() pitfall.
Encode text to Base64 or decode it back, with URL-safe and UTF-8 options — a Base64 encoder and decoder in one.
Loading tool…
The tool is loading its code on your device. This happens once and is cached for later visits.
Processed entirely on your device
Overview
Free Base64 encoder and decoder for text and files. Handles UTF-8 correctly, supports URL-safe alphabets, and explains decode failures. Nothing is uploaded.
A Base64 encoder exists because a lot of the internet's plumbing was designed for text. Email bodies, HTTP headers, XML attributes, JSON strings, CSS values and URL query parameters all historically choked on arbitrary bytes. A Base64 encoder translates any byte sequence into 64 characters that every one of those channels handles safely — and a Base64 decoder puts the original bytes back exactly as they were.
This Base64 converter handles both directions at once: encode Base64 from text or file bytes, decode Base64 back to text or a downloadable binary, with UTF-8 and URL-safe options where lesser tools quietly produce mojibake. It runs entirely in the browser, which matters when the string you are decoding is a token or a secret you would rather not paste into someone else's API.
The standard alphabet is A–Z, a–z, 0–9, + and /, with = as padding. Every six bits of input become one character, so three bytes become four characters.
The URL-safe alphabet replaces + with - and / with _. Both of the replaced characters are reserved in URLs: + means space in a query string, and / is a path separator. Padding is frequently dropped as well, and decoders are expected to tolerate its absence.
This is the single most common Base64 bug in JavaScript. atob() and btoa() operate on binary strings where each character code is one byte. If you pass a string containing é directly to btoa(), it throws or produces garbage, because é is code point 233 which is fine, but € is 8364 which is not representable in a single byte.
The correct round trip is:
TextEncoder → UTF-8 bytes → Base64 of those bytes.TextDecoder with UTF-8 → string.This tool does both steps. If you are writing the code yourself, skipping either one produces mojibake that looks like é or €.
It is not encryption, not hashing and not compression. There is no key, no digest and the output is 33% larger than the input. Encoding secrets in Base64 before storing or transmitting them is a real and persistent security mistake — it obscures a value from casual observation while providing no actual protection.
base64(username:password) — secure only because TLS wraps it.Text is the common case, but the alphabet does not care where the bytes came from. Dropping an image, a font or a binary file onto the Base64 encoder produces the same string a server would generate — and decoding a long string back through file mode returns a downloadable binary rather than a wall of replacement characters. That round trip is what makes a Base64 encoder useful for building data URIs, inspecting an embedded resource, or recovering a file someone sent you as inline text.
Failed decodes usually fail silently elsewhere: a wrong alphabet, a missing padding character, or a stray space or newline copied along with the string. This Base64 decoder separates those cases and names the one it met, so "invalid character at position 41" replaces a blank output. URL-safe mode handles strings that use - and _ in place of + and / — the form JWTs, S3 keys and Google APIs use — and tolerates stripped padding automatically.
Every encode and decode happens in your tab. Nothing is uploaded, nothing is logged, nothing is retained. For a format whose most common payloads are authentication headers, API credentials and signed tokens, an offline Base64 converter is not a luxury — it is the difference between debugging an auth problem and leaking the credential you were debugging with. Paste, convert, copy, close.
Base64 output is always a multiple of four characters, and the padding = signs exist to keep that promise when the input length is not a multiple of three bytes. One = means the final group encoded two bytes; two = means it encoded one. Some ecosystems strip the padding entirely — JWT is the notable one — and a robust decoder reconstructs it before converting. The length arithmetic is also how you sanity-check a decode: a valid Base64 string of N characters represents exactly 3 × N ÷ 4 bytes minus the padding, and any remainder after division by four means the string was truncated or corrupted somewhere in transit.
Step by step
Choose Encode or Decode, then paste your text or drop a file.
For encoding, confirm UTF-8 handling if the text contains accents, emoji or non-Latin script.
For decoding, select URL-safe mode if the string contains - or _ instead of + and /.
Press Convert and read the result alongside its byte length.
Copy the output, or download it as a text or binary file.
Why use it
What this tool is good for, and what it deliberately does not try to do.
Encodes through a proper UTF-8 byte conversion, so accented characters, CJK text and emoji round-trip instead of turning into mojibake — the classic atob() pitfall.
Switches between +/ and -_ alphabets and handles missing padding, which is what JWTs, S3 keys and most modern APIs actually use.
Encode a file's raw bytes and decode back to a downloadable binary, not just strings.
Invalid characters, bad padding and truncated payloads each produce a specific diagnosis instead of a generic failure.
Questions
Short, honest answers about quality, limits and privacy.