Developer Tools· 5 min read

Base64 Encoding: Why Emojis Break in Most Tools (And How to Fix It)

Understand what Base64 actually encodes, why naive implementations mangle Unicode, and how URL-safe variants differ.

By EasyDevTools Team Last updated: 2026-08-24

Base64 encodes bytes, not characters — and that's where things go wrong

Base64 is fundamentally a byte-to-text encoding: it takes arbitrary binary data and represents it using only 64 printable characters (A–Z, a–z, 0–9, plus two more symbols), safe to transmit through systems that only handle text. The critical detail is that Base64 doesn't know or care what those bytes represent — it just repackages binary data three bytes at a time into four output characters, regardless of whether those bytes came from an image, a file, or text.

This is exactly where naive implementations break on emojis and non-Latin text. JavaScript's built-in `btoa()` function assumes each character maps to a single byte using the Latin-1 (ISO-8859-1) encoding — fine for plain English text, but emojis, accented characters, and most non-Latin scripts are encoded in UTF-8 using multiple bytes per character. Pass a multi-byte UTF-8 character straight into `btoa()` and it either throws an error or silently corrupts the data, because it's trying to force multi-byte characters into a single-byte assumption that doesn't hold.

See it in action

Why this tool round-trips Unicode correctly

Instead of calling `btoa()` directly on raw text, this tool first runs the input through TextEncoder, which correctly converts a JavaScript string — Unicode code points and all — into its proper UTF-8 byte representation. Only those correctly-encoded bytes get passed to the Base64 conversion. Decoding reverses this: Base64 back to raw bytes, then TextDecoder interprets those bytes as UTF-8 to reconstruct the original string, emojis included. The distinction is subtle but total: one approach assumes text is always one byte per character, the other correctly handles the variable-width reality of UTF-8.

Standard vs. URL-safe Base64

VariantCharacters usedWhere it's needed
Standard Base64A–Z, a–z, 0–9, +, /Email attachments (MIME), general data storage
URL-safe Base64A–Z, a–z, 0–9, -, _URLs, query parameters, filenames, JWT tokens

Encoding and decoding text

Pick the mode: Encode (text → Base64) or Decode (Base64 → text).

Type or paste your input — the output updates live.

Use the swap button to feed the output back as input, useful for verifying a round-trip or chaining operations.

Click Copy to grab the result.

Why URL-safe Base64 exists at all

Standard Base64's `+` and `/` characters both carry special meaning inside a URL — `+` can be interpreted as a space in query strings, and `/` is a path separator — so putting standard Base64 output directly into a URL risks it being misinterpreted or requiring additional escaping. URL-safe Base64 solves this by substituting `-` for `+` and `_` for `/`, two characters with no special meaning in URLs, at the cost of no longer being standard Base64 that every decoder recognizes by default.

When decoding, this tool automatically converts `-` and `_` back to `+` and `/` before decoding, so you can paste either variant into the decode field without first figuring out which one you're looking at.

Why size isn't really a hard limit, but chunking still matters

Base64 encoding involves converting the entire input into an array of character codes before processing — done naively in one pass, a sufficiently large input can exceed the JavaScript engine's call stack limits when using certain conversion approaches (like spreading a huge byte array into function arguments). This tool processes data in 32KB chunks specifically to avoid that stack overflow, which means there's no hard size ceiling imposed by the tool itself; the real limit is simply how much your device's memory can hold and process.

Common mistakes

Assuming a Base64 string decodes to a specific known format (an image, for instance) — decoding here shows the raw decoded text; for image data URLs specifically, use a dedicated image converter that expects that structure.

Pasting URL-safe Base64 into a tool expecting standard Base64 (or vice versa) and getting a decode error — this tool handles both automatically, but not every Base64 tool does.

Expecting a naive Base64 tool to handle emojis or accented characters correctly — many tools built on `btoa()` alone will corrupt or reject them outright.

Treating Base64 as a form of encryption — it's purely an encoding scheme with no key or secret involved; anyone can decode it instantly, so it provides no confidentiality at all.

Real use cases

Encoding a string containing emojis or non-English text for embedding in a system that only accepts plain ASCII.

Decoding a Base64-encoded value found in an API response or JWT payload to inspect its actual content.

Preparing a URL-safe encoded string for use as a query parameter or in a filename, where standard Base64's `+` and `/` would cause problems.

Round-tripping data through the swap button to verify an encoding or decoding step behaves as expected before using it in code.

Frequently asked questions

Q: Why do emojis break in other Base64 tools?

A: Many tools call `btoa()` directly, which only supports Latin-1. This tool uses TextEncoder/TextDecoder so UTF-8 characters, including emojis, round-trip correctly.


Q: Does it support URL-safe Base64?

A: Yes. When decoding, the tool automatically converts the URL-safe `-` and `_` characters to `+` and `/` before decoding.


Q: Is there a size limit?

A: Only your device's memory. The tool processes data in 32KB chunks to avoid stack overflow on large inputs.


Q: Can I decode Base64 images?

A: You can decode Base64 to its raw bytes, but for image data URLs you'll want a dedicated image converter — this tool shows the decoded text rather than rendering it as an image.


Q: Is anything sent to a server?

A: No. Encoding and decoding happen entirely in your browser.


Q: Why does a short piece of text produce a noticeably longer Base64 string?

A: Base64 represents every 3 bytes of input as 4 output characters, which is roughly a 33% size increase — it's a trade-off for using only text-safe characters, not a flaw in the encoding.

Try it now

Encode or decode your text with Base64 Encode / Decode. Working with structured data? Try the JSON Formatter. Need to encode for a URL specifically? Use URL Encode / Decode, or inspect a token's Base64-encoded payload with the JWT Decoder.

Need help using this tool?

Read our complete Base64 Encode / Decode tutorial for step-by-step guidance.

Ready to try the tool?

No accounts. No uploads. No limits. Start now.