JavaScript Base64 Encode & Decode
Encode and decode Base64 strings online β with JavaScript btoa/atob examples, Node.js Buffer tips, and UTF-8 gotchas.
π 100% private β runs entirely in your browserEncode and decode Base64 strings online β with JavaScript btoa/atob examples, Node.js Buffer tips, and UTF-8 gotchas.
π 100% private β runs entirely in your browserJavaScript provides btoa() and atob() for Base64 encoding and decoding in the browser. Node.js offers Buffer.from() with built-in Base64 support. Both have important UTF-8 caveats to be aware of.
btoa/atob in the browser.Buffer.from(str).toString('base64').+ with - and / with _.// Simple ASCII encoding
const encoded = btoa("Hello, World!");
console.log(encoded); // "SGVsbG8sIFdvcmxkIQ==" // Decode back
const decoded = atob("SGVsbG8sIFdvcmxkIQ==");
console.log(decoded); // "Hello, World!"// btoa() fails on non-Latin-1 characters
// Use TextEncoder for UTF-8 support function utf8ToBase64(str) { const bytes = new TextEncoder().encode(str); let binary = ""; bytes.forEach(b => binary += String.fromCharCode(b)); return btoa(binary);
} function base64ToUtf8(b64) { const binary = atob(b64); const bytes = Uint8Array.from(binary, c => c.charCodeAt(0)); return new TextDecoder().decode(bytes);
} console.log(utf8ToBase64("caf\u00e9")); // "Y2Fmw6k="
console.log(base64ToUtf8("Y2Fmw6k=")); // "caf\u00e9"// Node.js has native UTF-8 support via Buffer
const encoded = Buffer.from("Hello, caf\u00e9!").toString("base64");
console.log(encoded); // "SGVsbG8sIGNhZsOpIQ==" const decoded = Buffer.from(encoded, "base64").toString("utf-8");
console.log(decoded); // "Hello, caf\u00e9!"// Standard Base64 uses + and / which are unsafe in URLs
// base64url replaces + with - and / with _ function toBase64Url(str) { return btoa(str) .replace(/\+/g, "-") .replace(/\//g, "_") .replace(/=+$/, ""); // strip padding
} // Node.js 16+ has built-in base64url
Buffer.from("data").toString("base64url");btoa('caf\u00e9') works, but btoa('\ud83d\ude00') throws InvalidCharacterError. Any character above U+00FF requires encoding via TextEncoder first. This is the number one Base64 bug in JavaScript.
atob() returns a "binary string" where each character represents one byte. For multi-byte UTF-8, you must convert through Uint8Array and TextDecoder to get the correct string back.
Buffer.from(str).toString('base64') handles UTF-8 natively β no extra steps needed. In the browser, you need the TextEncoder workaround. Code that works in Node.js may break in the browser and vice versa.
Standard Base64 uses +, /, and = padding β all problematic in URLs. Use base64url encoding (replace + with -, / with _, strip =) for URL-safe tokens and JWTs.
For ASCII strings, use btoa(string). For UTF-8 text with special characters, first encode with TextEncoder, convert bytes to a binary string, then call btoa(). In Node.js, use Buffer.from(string).toString('base64').
btoa() only accepts characters in the Latin-1 range (U+0000 to U+00FF). Characters like emoji, Chinese, Japanese, or Arabic throw InvalidCharacterError. Use the TextEncoder + btoa pattern or Buffer.from() in Node.js.
btoa() is a browser API that only handles Latin-1 characters directly. Buffer.from(string).toString('base64') is Node.js-specific and handles UTF-8 natively without extra encoding steps.
base64url is a URL-safe variant of Base64 that replaces + with -, / with _, and optionally strips = padding. It's used in JWTs, data URIs in URLs, and anywhere Base64 appears in a URL context. Node.js 16+ supports it natively with toString('base64url').
Yes. All encoding and decoding happens entirely in your browser. Your data is never sent to any server.