Why JSON arrives Base64-encoded
Base64 exists to move binary-safe data through channels that only reliably carry text. JSON is already text, so encoding it looks redundant — until you meet the places where it genuinely helps. A JWT stores its header and payload as base64url segments. Kubernetes secrets hold their values encoded. Message queues, webhook envelopes and data: URIs all wrap a payload so that quotes, newlines and non-ASCII characters cannot disturb the outer format.
The cost is that the moment something goes wrong, you are staring at an unreadable block of letters. This tool collapses the two steps you would otherwise do by hand — decode, then format — into one paste.
Decoding, step by step
- Whitespace is stripped, so a payload wrapped across several lines works as-is.
- URL-safe characters are normalized:
-becomes+and_becomes/. - Missing
=padding is restored, which JWT segments almost always need. - The bytes are decoded as UTF-8, then parsed and pretty-printed as JSON.
Encoding back
Switch the toggle to Encode and the flow reverses: your JSON is parsed to check it is valid, re-serialized compactly so no whitespace is wasted, encoded as UTF-8 bytes, and then converted to Base64. Because the document is minified first, the encoded string is as short as the data allows.
Command-line equivalents
# decode and format
echo "$B64" | base64 --decode | jq .
# encode a file, no line wrapping
jq -c . payload.json | base64 -w0
# Python
import base64, json
json.loads(base64.b64decode(encoded))
# JavaScript
JSON.parse(atob(encoded)) # ASCII only — see belowThe UTF-8 trap
atob returns a binary string, one character per byte. If your JSON contains an emoji or an accented name, those bytes need to be reassembled before they are read as text — otherwise you get mojibake. The correct browser approach decodes to a Uint8Array first and passes it through TextDecoder, which is exactly what this page does. In Python,base64.b64decode returns bytes and json.loads accepts them directly, so the problem does not arise.
Nothing is transmitted
Base64 is an encoding, not encryption — anyone holding the string holds the data. That makes it worth checking where you decode it. Every step here runs in your browser with no network request, so the payload never leaves your machine. See theprivacy page for details.
Size, and why it matters
Base64 encodes three bytes as four characters, so the output is always about 33% larger than the input. That overhead is invisible on a small config value and expensive on anything sizeable — embedding a megabyte of JSON in a data URI costs you a third of a megabyte for nothing, and because the result is a single opaque token, no compression-aware layer in between can do much with it.
Two rules of thumb follow. Encode late and decode early, so the enlarged form exists for as short a span as possible. And where you control both ends, prefer sending JSON directly with the right content type over wrapping it — the wrapping usually exists to work around a constraint that no longer applies.
Standard versus URL-safe alphabets
The original alphabet ends with + and /, both of which have meaning inside a URL — one is a space in a query string, the other a path separator. base64url swaps them for - and _ and usually drops the = padding, since its length is derivable. That is what JWTs use, and it is why pasting a token segment into a strict decoder often fails on the padding rather than the content. This tool accepts both forms and restores the padding itself, so you can paste a segment straight from a debugger without cleaning it up first.