Base64 Encode & Decode

Free online Base64 encoder and decoder. UTF-8 safe, works offline, runs entirely in your browser.

encoding

Base64

Output
Waiting for input…

Runs entirely in your browser. Your input never leaves your device.

What next?

How it works

What Base64 actually is

Base64 is an encoding — a way to represent arbitrary binary data using only the 64 printable ASCII characters A–Z, a–z, 0–9, +, /. It is defined by RFC 4648 and was invented in the 1980s so binary attachments could survive email systems that only handled 7-bit text.

It is not encryption. Anyone with the encoded string can decode it back to the original — there is no key, no secret. If you need confidentiality, use AES or your TLS layer; Base64 only solves "how do I transport bytes through a text-only channel?".

The transform itself is mechanical: every 3 bytes of input become 4 output characters. Input that doesn't divide evenly into 3-byte groups gets padded with = so the output length is always a multiple of 4. This is why you see = at the end of some encoded strings (zero, one, or two of them).

When you'll reach for it

  • Data URIs. Inlining a small image into CSS or HTML: url("data:image/png;base64,iVBOR…").
  • JWT. Each segment of a JSON Web Token is Base64URL-encoded JSON.
  • HTTP Basic auth. The Authorization: Basic … header is user:pass Base64-encoded.
  • Email attachments (MIME). Binary files survive transit by being Base64-wrapped.
  • API payloads. Sending binary blobs over JSON (which has no native binary type).
  • Storing binary in databases or environment variables that expect text.

You should not use Base64 to "shrink" data — it adds ~33% overhead. It's a transport encoding, not a compression.

The UTF-8 gotcha

The browser's built-in btoa() function looks like it does the right thing — and silently produces garbage the moment you feed it a non-ASCII character:

btoa('Hello')      // "SGVsbG8="              ✓
btoa('世界')        // InvalidCharacterError   ✗
btoa('🌏')         // InvalidCharacterError   ✗

The reason: btoa operates on Latin-1 (bytes 0–255), not UTF-8. The character doesn't fit in one byte, so the function refuses. Same for emoji, Vietnamese with diacritics, Arabic, anything outside basic Latin.

The fix is to UTF-8 encode the string first into a byte sequence, then Base64-encode those bytes. That's exactly what this tool does — every input is treated as UTF-8 by default, so emoji and unicode round-trip cleanly.

Base64 vs Base64URL

Standard Base64 uses + and /, which both have special meanings in URLs and filenames. Base64URL (RFC 4648 §5) swaps them for - and _, and strips the trailing = padding. This makes encoded strings safe to drop into a URL query parameter, a JWT segment, or a filename.

If you toggle URL-safe above, the tool emits - and _ instead of + and /, with no padding. Decoding accepts either flavor — we auto-detect.

Examples

Encode plain text:

Input: Hello, World! Output: SGVsbG8sIFdvcmxkIQ==

Encode Vietnamese with diacritics:

Input: Tiếng Việt có dấu Output: VGnhur9uZyBWaeG7h3QgY8OzIGThuqV1

Decode a JWT payload chunk (Base64URL):

Input: eyJzdWIiOiIxMjM0NTY3ODkwIn0 Output: {"sub":"1234567890"}

Security notes

  • Never store passwords as Base64. It's reversible. Use a password hash function (bcrypt, argon2, scrypt) instead.
  • Don't trust Base64-decoded JSON without re-validating. A JWT signature is what proves integrity; the Base64 layer alone proves nothing.
  • Watch input size when decoding. A few KB of Base64 expands to a few KB of bytes — fine — but a few hundred MB at once can crash a browser tab. This tool processes input synchronously; for very large files prefer a streaming approach.

Privacy

This page runs the encoding/decoding logic entirely in your browser using the open-source js-base64 library. Your input is never sent to our servers, never logged, and never leaves your device. Open the network tab and try it — you'll see zero requests.

Related tools

  • JWT Decoder — inspect a JSON Web Token (which is three Base64URL chunks).
  • URL Encoder — for percent-encoding in URLs, a different (often complementary) encoding.

FAQ

Is Base64 encryption?

No. Base64 is a reversible encoding — anyone holding the encoded string can decode it back to the original without a key. Use it to transport binary data through text-only channels, not to keep secrets.

Why does btoa() break on emoji or Vietnamese text?

The browser's native btoa() only handles Latin-1 (bytes 0–255). Characters like or 🌏 are multi-byte in UTF-8 and don't fit, so btoa throws. This tool encodes UTF-8 first, then applies Base64 — so unicode survives the round trip.

What's the difference between standard Base64 and Base64URL?

Standard Base64 uses + and / and pads with =. Base64URL replaces +/ with -_ and drops the padding, making the result safe to use in URLs, JWT segments, or filenames. Toggle "URL-safe" above to switch alphabets.

Why do I see = at the end of some encoded strings?

Base64 encodes every 3 input bytes as 4 output characters. When the input length isn't a multiple of 3, the encoder pads the output with one or two = characters so the total length stays divisible by 4. Base64URL omits this padding.

Is my input sent to a server?

No. All processing happens in your browser via the js-base64 library. Open your browser's network tab — you will see zero requests while you type. The page works offline once cached.

What's the largest input this can handle?

Practically, a few megabytes per operation. Beyond ~10 MB you may notice the browser tab pausing while the conversion runs synchronously. For multi-hundred-MB files, prefer a streaming decoder in a Web Worker or a server-side tool.

My decoded text looks like garbage — what went wrong?

Almost always one of three things: (1) the input is encoded with a different alphabet (URL-safe vs standard — try toggling), (2) the input was truncated and is missing padding, or (3) the original wasn't UTF-8 text but binary that happens to be invalid UTF-8 (then "decoded text" is meaningless; you want the raw bytes).

Can I use Base64 to compress data?

No — Base64 makes data ~33% larger, not smaller. If you need to shrink, use gzip, brotli, or a domain-specific codec, then Base64-encode the compressed bytes if you need to transport them as text.