How it works
Base64 is a binary-to-text encoding that maps every 3 input bytes to 4 ASCII characters drawn from A–Z a–z 0–9 + /. It's used anywhere binary data needs to ride through a text-only channel — JSON payloads, URLs, email attachments, data URIs, JWT segments.
The tricky part is text encoding. Browsers' built-in btoa() only handles characters in the Latin-1 range (0–255), so if you naively call btoa("héllo") you'll get a InvalidCharacterError. The fix is to first encode the string as UTF-8 bytes (using TextEncoder), then base64 those bytes. Decode reverses the trip: base64 → bytes → UTF-8 string.
URL-safe base64 (RFC 4648 §5) substitutes + with - and / with _ so the output can sit unescaped in a URL or filename. JWTs use it. This tool's decode side accepts both flavours and re-pads automatically.
Examples
-
"Hello, world!"→SGVsbG8sIHdvcmxkIQ== -
"héllo"→aMOpbGxv(UTF-8 safe — naive btoa fails) -
"🚀 ship it"→8J+agCBzaGlwIGl0
FAQ
- Is anything I paste sent to a server?
- No. The encode and decode both run in your browser via
TextEncoder,btoa, andatob. Nothing leaves your machine. - Why does my emoji-laden text decode wrong on other base64 sites?
- Most one-liner
btoaimplementations break on multi-byte UTF-8. This tool encodes the string as UTF-8 bytes first, then base64 the bytes — which round-trips emoji and CJK correctly. - Does this support URL-safe base64?
- Decode is permissive:
-and_are remapped to+and/, and missing padding is added. Encode emits standard base64 with padding. - What's the maximum input size?
- There's no fixed cap — the limit is your browser's memory. A few megabytes is fine. For multi-gigabyte payloads, use a streaming library locally instead.
- Why does base64 inflate the size by ~33%?
- Base64 represents 3 bytes of input as 4 ASCII characters of output, plus padding. So 100 bytes in becomes ~136 bytes out. That's the cost of "ASCII-safe transport".
Common pitfalls
- Calling
btoa()on non-Latin-1 strings throwsInvalidCharacterError— UTF-8 encode first. - Forgetting padding (
=at the end) when decoding URL-safe variants. This tool re-pads automatically. - Treating base64 as encryption. It isn't — it's just an encoding. Anyone can decode it.
- Confusing base64 with
encodeURIComponent. They serve different purposes (binary-safe vs URL-safe text).
In your code
// no install needed — use the platform // UTF-8 safe encode
const utf8ToBase64 = (s) =>
btoa(String.fromCharCode(...new TextEncoder().encode(s)));
// UTF-8 safe decode
const base64ToUtf8 = (b) => {
const bin = atob(b);
const bytes = Uint8Array.from(bin, c => c.charCodeAt(0));
return new TextDecoder().decode(bytes);
}; npm i base-64 import { encode, decode } from 'base-64';
const encoded = encode('héllo'); // 'aMOpbGxv'
const decoded = decode(encoded); // 'héllo' # stdlib — no install import base64
encoded = base64.b64encode('héllo'.encode('utf-8')).decode('ascii')
# 'aMOpbGxv'
decoded = base64.b64decode(encoded).decode('utf-8')
# 'héllo' Related tools
- URL Encode / Decode
URL encode / decode with three variants: encodeURIComponent, encodeURI, and form-urlencoded.
- UUID Generator (v4 / v7)
Generate UUID v4 (random) or v7 (time-ordered). Bulk regenerate up to 100 at once.
- Unix Timestamp Converter
Convert between unix timestamps (seconds or ms) and human dates (ISO, RFC, local).
- JWT Decoder
Decode JWT header and payload, see expiration status. No signature verification.