JSON Input

Base64 Output

Success
Warning

Why encode JSON at all

Somewhere in your stack is a slot that will only hold a plain, boring string. An environment variable that gets shell-expanded. A Kubernetes Secret, whose data: values must be Base64 whether or not the content needs it. A query parameter carrying saved filter state. An XML attribute that would choke on a raw <. Base64 exists for exactly this: take arbitrary bytes, write them in 64 characters that nothing along the way will reinterpret, and get them out unchanged at the other end.

Paste JSON on the left, take the encoded string from the right. It never leaves the tab, which is the reason to use a page rather than an online service you know nothing about when the document holds credentials.

The part worth being careful about is character encoding, and the browser makes it easy to get wrong. btoa() takes a "binary string" — one character per byte — so anything past code point 255 throws. What it does below 255 is more dangerous, because it does not throw at all: btoa('café') happily returns Y2Fm6Q==, which is Latin-1. UTF-8 wants Y2Fmw6k=. Nothing warns you, and the mojibake turns up later on a machine you cannot debug. MDN says so directly in the notes on that function.

Everything here goes through TextEncoder first, so the bytes are UTF-8 — which is what RFC 8259 requires of JSON exchanged between systems anyway. An accented operator name, a Japanese product title and an emoji in a display field all come out the same on the other side.

Encoding a document

  1. Paste or upload your JSONIt does not have to be valid — Base64 has no opinion about the bytes. Invalid JSON is still encoded, with a note saying so, because encoding a fixture or a fragment on purpose is a legitimate thing to be doing.
  2. Pick the output formatStandard is what most APIs mean. URL-safe swaps + and / for - and _ and drops padding, for query strings and token segments. MIME wraps at 76 columns, matching openssl base64 and email attachments.
  3. Decide whether to minify firstEncoding pretty-printed JSON encodes the whitespace too, at the same 33% markup. Tick Minify and the indentation goes before the bytes are counted — normally what you want for a URL or an environment variable, and irrelevant for a Kubernetes secret nobody will read by hand.
  4. Copy it outThe chain icon copies the result as a complete data:application/json;base64,… URI, ready to paste. The plain copy gives you just the encoded string.

If the destination is a URL, use the URL-safe variant rather than percent-encoding a standard one. Standard Base64 contains +, which is a legal literal space in a query string — so a token round-tripped through a form or a badly written proxy can come back with its + characters turned into spaces, and it will fail intermittently in a way that looks like a server problem.

The accented character that quietly breaks things

Two encodings of the same two-key document. The top one is UTF-8, which is what this page produces and what every consumer expects. The bottom is what you get from btoa() in a browser console — no error, no warning, and an é that arrives as a replacement character wherever it lands.

the same JSON, encoded two ways utf-8, not latin-1
operator.jsonTwo accented characters
{
  "operator": "Télécom Générale",
  "apn": "internet"
}
encodedCompare the run after "IlT"
# this page (utf-8, correct)
eyJvcGVyYXRvciI6IlTDqWzDqWNvbSBH
w6luw6lyYWxlIiwiYXBuIjoiaW50ZXJu
ZXQifQ==

# btoa() in the console (latin-1)
eyJvcGVyYXRvciI6IlTpbOljb20gR+lu
6XJhbGUiLCJhcG4iOiJpbnRlcm5ldCJ9

Where this actually gets used

Putting a config into an environment variable

A JSON blob with quotes, braces and newlines does not survive a shell, a Dockerfile ENV line and a CI settings box unscathed. Encoding it once turns it into a single unbroken token that nothing along the path will reinterpret, and the receiving process decodes it at startup.

Writing a Kubernetes Secret by hand

Every value under data: has to be Base64 — kubectl does it for you with --from-file, but the documented workflow is not always what you are doing when you are editing a manifest in a review. Encode here and paste. Worth repeating that this is encoding and not protection: anyone with read access decodes it as easily as you just encoded it.

Embedding a small fixture in a page or a test

A data URI keeps a sample payload in the file that uses it, with no extra request and no asset to keep in sync. The 33% size penalty makes it a poor idea for anything large, but for a fixture of a few hundred bytes it is tidier than a second file.

Passing state through a URL

Saved filters, a share link, the state of a form — encode the JSON URL-safe and it becomes one parameter with no escaping to think about. Keep an eye on length: browsers are generous but proxies and access logs are not, and a truncated URL fails in a way that is genuinely hard to trace.

What it does

  • UTF-8, always. Accented characters, CJK text and emoji encode correctly instead of throwing or silently degrading to Latin-1 the way btoa() does.
  • Three output formats. Standard, URL-safe without padding, and MIME wrapped at 76 columns — the three you actually meet.
  • Optional minify, without wrecking long numbers. Minifying re-serialises the document, so a 19-digit ICCID would normally be rounded on the way through. It is read from the source text instead and written back exactly.
  • A size readout. Bytes in, characters out, and the growth as a percentage — useful before you commit to a data URI.
  • One-click data URI. Copies the complete data:application/json;base64, string, with any line wrapping removed, because a URI containing a newline is not a URI.
  • Nothing is uploaded. Encoding happens here, in this tab.

Questions that come up

Does encoding make my JSON secure?

Not in the slightest. Base64 is reversible by anyone, with no key and no effort — the decoder on this site does it in one paste. It solves transport, not confidentiality. If the content is sensitive it needs encryption underneath, and the encoding is just how the ciphertext gets carried.

Which variant should I pick?

Standard unless something tells you otherwise — it is RFC 4648 §4 and it is what most libraries produce by default. URL-safe if the string is going into a URL or a token segment. MIME only if the consumer expects wrapped lines, which in practice means email or something built on top of openssl.

Why did my output get 33% bigger?

Three bytes become four characters, so the ratio is 4/3 before padding. That is inherent to the alphabet, not something a better encoder would avoid. If size matters, minify first and compress before encoding rather than after — Base64 output compresses poorly, which is the opposite of what people assume.

My URL-safe output has no = at the end. Is that a problem?

No. Padding tells a decoder where the last group ends, and the length already implies it, so §3.2 of the spec allows it to be omitted where the length is known. JWTs drop it as a matter of course. If a strict consumer complains, switch to standard output and it comes back.

Can I encode something that is not JSON?

Yes — it is encoded anyway, with a note pointing out that it did not parse. If you are working with a different format there are dedicated pages: XML to Base64, YAML to Base64, and Text to Base64 for anything else.

Will a long ID come back exactly?

Yes, in both modes. Encoding without minifying does not parse the document at all, so nothing can be lost. With minifying on, the document is re-serialised — the usual place a 19-digit number becomes one ending in 000 — and the digits are taken from the source text to prevent it. The article on large numbers explains why that happens everywhere else.

Related tools

Worth reading