← Back to home

Base64 Encoder & Decoder

Last reviewed on April 27, 2026.

Paste text into either box and the other one updates as you type. UTF-8 is handled correctly, so non-ASCII input round-trips without mojibake. Switch to URL-safe mode if the encoded output needs to ride in a URL or a JWT.

Encoded ↓  ·  both fields are editable
Edits flow both directions.

What Base64 actually is

Base64 is a way of writing binary data using only sixty-four printable characters: A–Z, a–z, 0–9, plus two extras (+ and / in standard, - and _ in URL-safe). The encoder takes three input bytes (24 bits), splits them into four 6-bit groups, and emits one Base64 character per group. The output is roughly 4/3 the length of the input, plus padding.

It is not encryption. It is not compression. It is a transport format — designed for systems that historically did not handle the full range of byte values cleanly, like email (SMTP) and URL parameters.

Standard vs. URL-safe

The two variants differ in only two characters and the padding rule:

StandardURL-safe
62nd character+-
63rd character/_
Padding= required= often omitted
Where it shows upEmail attachments, data: URLs, most APIsJWTs, query parameters, OAuth state tokens

Use URL-safe whenever the output sits in a URL, a cookie, or a header. The + and / in standard Base64 are reserved characters in URLs and would have to be percent-encoded — defeating the point of using Base64 for compactness.

UTF-8 and why it matters

JavaScript strings are UTF-16 internally. Naively passing a string to btoa() fails on any character outside Latin-1 (btoa("日本") throws). The tool above first encodes the input as UTF-8 with TextEncoder, so emoji, CJK characters, accented Latin, and everything else round-trips cleanly. Decoding reverses that — bytes out, then TextDecoder('utf-8') back to a string.

If you are decoding output from a system that does not use UTF-8 (rare, but it happens with old Windows COBOL exports or Latin-1 email bodies), the resulting bytes will appear as garbled characters. That is a charset mismatch, not a Base64 bug.

Worked example

The string Hi! encodes as follows:

  1. UTF-8 bytes: 0x48 0x69 0x21 (binary 01001000 01101001 00100001).
  2. Split into 6-bit groups: 010010 000110 100100 100001.
  3. Map each group to its Base64 alphabet index: 18 → S, 6 → G, 36 → k, 33 → h.
  4. Result: SGkh.

No padding is needed because the input was a multiple of 3 bytes. If the input is 1 byte short of a multiple of 3, the encoder appends ==; if it is 2 bytes short, it appends =. URL-safe Base64 commonly omits the padding because the receiving end can recompute it from the length.

Common mistakes

Where this fits with the other tools on the site

Pair Base64 with the URL encoder when you are debugging a request that double-encodes its parameters. For inspecting JSON payloads after a Base64 round-trip, send the decoded text through the JSON formatter. When you are generating prop data for a screen recording, the fake prop-data generator covers IDs and hashes; combine it with this tool when the recording shows a JWT-like token.