Base64 is a way to write arbitrary bytes using only safe, printable characters — nothing more. The name comes from its alphabet: exactly 64 characters (A–Z, a–z, 0–9, + and /), plus the = sign reserved for padding. Because those characters survive every text-only channel — HTTP headers, JSON strings, XML, email bodies, URLs — Base64 lets bytes go places that would otherwise corrupt them.
Why 64 characters? Because 64 = 2⁶: each output character carries exactly 6 bits, so the mapping between bytes and characters is pure bit-shifting with no ambiguity. The cost is size. The encoder reads the input 3 bytes at a time (24 bits), splits them into four 6-bit groups, and emits one character per group:
Man → TWFu — Every Base64 string you will ever meet works exactly like this one — including the ones hiding in JWTs and data URIs.
= tops the length up to a multiple of 4 when the input isn't an even multiple of 3 bytes.dXNlcjpwYXNz can read it. Never treat a Base64-encoded password or API key as protected.You rarely decide to use Base64 — you find it waiting in an API response, a header or a config file. Each card below is one of those moments: what you see, what to do on this page, and what you get.
A URL like data:image/png;base64,iVBORw0KGgo… embedded in HTML, CSS or a webpack bundle.
Copy everything after base64,, paste it here, press Decode & Format.
For text payloads (SVG source, JSON, CSV) you get readable content back. True binaries such as PNG come out as gibberish characters — see Gotchas below; this page decodes to text, not to files.
A token like eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjMifQ.sig — three dot-separated segments whose first two always start with eyJ, which is simply the opening of a JSON object after encoding.
Copy the middle segment between the dots, paste it here, press Decode & Format. Or open the whole token in the JWT Debugger.
The claims payload pretty-printed as JSON in its own tab, ready for Tree/Table view. URL-safe - and _ characters are handled automatically.
An HTTP header like Authorization: Basic dXNlcjpwYXNz in a request dump or proxy log.
Copy just the part after Basic, paste it here, press Decode & Format.
The credentials in cleartext — here user:pass. A useful reminder that Basic auth only protects anything because it rides inside HTTPS.
A wall of wrapped letters under Content-Transfer-Encoding: base64 when viewing an email's source or an .eml file.
Join the wrapped lines into one single-line string first (internal line breaks are not part of the alphabet), then paste and press Decode & Format.
The message part's text content. Attachments that are real binaries decode to noise for the same reason PNG data URIs do.
A field like "payload": "eyJ1c2VySWQiOjQyfQ==" inside an API response — some service stuffed encoded data where text was expected.
Copy the value, paste it here, press Decode & Format.
A new numbered tab with the decoded content formatted as JSON — your original response stays untouched in the editor, and you can compare both side by side.
Two directions, two buttons, zero configuration. Both run entirely in your browser — nothing is uploaded, nothing is logged.
+ and /) with correct = padding.= padding.Single-box encoder sites make you work one string at a time. This page keeps a whole session:
Each decode opens a numbered tab — Base64 #1, Base64 #2, … — instead of overwriting your work. Your original Base64 lives in the root editor: the + button at the end of the tab bar returns to it, and switching tabs preserves every tab's content. Close tabs with the ✕ on hover; closing the last tab returns you to the encoder.
Hover any tab and click the ⇄ icon, then click the ⇄ icon on a second tab. A hint bar confirms the selection, and both contents open side by side on the JSON compare page with their tab labels — perfect for spotting why two supposedly identical decoded payloads differ.
When a decode produces JSON, the toolbar switches to the full formatter set: Code / Tree / Table views, search, Format, Minify, Anonymize, Escape/Unescape, plus Copy, Paste, Upload and Download. Non-JSON decodes stay simple text.
Ninety percent of "my Base64 doesn't work" reports fall into five buckets:
| Symptom | Cause | Fix |
|---|---|---|
| Rejected with “Content is not a valid Base64 string.” | The validator found a character outside the alphabet — usually a space, newline or quote copied along with the string — or the length leaves a leftover character after removing padding. | Re-copy the exact string without surrounding quotes, join any wrapped lines, and check nothing was truncated at either end. |
| Works with this tool but fails elsewhere (or vice versa) | Missing = padding. Many decoders require the length to be a multiple of 4; this page pads automatically, strict tools don't. | Append = until the length divides by 4 before feeding a stricter decoder. |
| A JWT segment fails to decode somewhere else | JWTs use base64url: + becomes - and / becomes _, often with padding stripped entirely. | Here it's automatic — both alphabets are accepted and normalized. Elsewhere, replace -/_ with +// and re-pad first. |
Decoded output is gibberish like �PNG | The payload was real binary (an image, zip, font). Decoding produced the correct bytes; rendering them as UTF-8 text produces replacement characters. | Nothing is corrupt — you just can't show bytes as text. For binaries use file-oriented tooling or serve them via a data URI instead. |
| Email-style Base64 won't validate | MIME wraps output at 76 columns. Only outer whitespace is trimmed here; line breaks inside the string are illegal characters. | Join the lines into one string (a quick find-and-replace of newlines does it) and decode again. |
| “It's Base64, so my API key is hidden, right?” | No. Encoding adds zero secrecy — every decoder, including this one, reverses it instantly. | Protect secrets with encryption or hashing on a server, keep them out of client code entirely, and rotate any key that has already shipped Base64-encoded. |
The same operations away from this page — identical inputs give identical outputs:
| Command / syntax | What it does |
|---|---|
| btoa('Man') // 'TWFu' | Browser JS encode. Latin-1 only — throws on emoji or any character above U+00FF. |
| atob('TWFu') // 'Man' | Browser JS decode. |
| btoa(String.fromCharCode(...new TextEncoder().encode(s))) | Unicode-safe encode trick — the same approach this tool uses internally, chunked for large inputs. |
| echo -n 'Man' | base64 # TWFu | CLI encode. The -n suppresses echo's newline — without it you encode Man\n and get TWFuCg==. |
| echo 'TWFu' | base64 -d # Man | CLI decode (GNU coreutils). macOS uses --decode or -D; GNU also offers -w 0 to disable 76-column wrapping. |
| data:[mediatype][;base64],DATA | Data URI anatomy — e.g. data:text/plain;base64,SGVsbG8=. Everything after the comma is pure Base64. |
| header.payload.signature | JWT anatomy: three base64url segments. Header and payload decode to JSON; the signature decodes to raw bytes and shouldn't be readable. |
No. Encoding, decoding, validation and formatting all happen in your browser with JavaScript. There is no backend round-trip — after the page loads, the tools even keep working offline.
Yes. URL-safe characters - and _ are normalized automatically, and missing padding is tolerated. Note that a whole dotted token is not itself valid Base64 — decode segments individually, or use the dedicated JWT Debugger which handles the anatomy for you.
No — output always uses the standard alphabet (+, /, =). If a target system needs the URL-safe variant, swap +→-, /→_ and strip trailing = yourself.
Deliberate design. Your original string stays in the root editor while each result gets its own numbered tab, so you can decode several payloads in a row, inspect each one, and hand any two of them to the compare page without re-pasting.
There is no artificial cap — the practical limit is your browser tab's memory. Multi-megabyte strings process comfortably on desktop; encoding runs through chunked conversion to avoid call-stack limits, so very long inputs don't crash the way naive one-shot btoa calls can.
Completely free, no account, no usage limits, no watermarks. Like every tool on this site, it runs entirely on your device — your payloads are never sent to or stored on a server.
Working with tokens? The JWT Debugger decodes complete tokens — header, payload and signature checks included — which pairs naturally with this page's segment-by-segment decoding. To edit or inspect a decoded payload further, use the JSON Formatter; to diff two decoded results, the JSON Compare tool picks up right where tab-to-tab compare hands off.
Paste text or Base64 below — encode, decode straight into formatted JSON with tabbed sessions and side-by-side compare. Everything runs locally in your browser.
Paste Text or Base64 to get started