Base64 Encode & Decode in JavaScript
Encode or decode below — it runs locally in your browser — then grab the canonical JavaScript code. The built-in btoa() and atob() only handle Latin-1, so Unicode text needs TextEncoder / TextDecoder first.
Encode and decode a string
For plain ASCII, btoa() encodes and atob() decodes:
// Encode
const encoded = btoa("Hello, world!");
console.log(encoded); // "SGVsbG8sIHdvcmxkIQ=="
// Decode
const decoded = atob("SGVsbG8sIHdvcmxkIQ==");
console.log(decoded); // "Hello, world!"
For Unicode (emoji, accents, non-Latin scripts), encode to UTF-8 bytes first, then convert to a binary string for btoa():
// Unicode-safe encode
function encodeBase64(str) {
const bytes = new TextEncoder().encode(str);
const binary = String.fromCharCode(...bytes);
return btoa(binary);
}
// Unicode-safe decode
function decodeBase64(base64) {
const binary = atob(base64);
const bytes = Uint8Array.from(binary, c => c.charCodeAt(0));
return new TextDecoder().decode(bytes);
}
encodeBase64("Hello 🌍"); // "SGVsbG8g8J+MjQ=="
Tip: btoa() only accepts Latin-1 (code points 0–255). Passing emoji or accented text raises InvalidCharacterError — always run Unicode strings through TextEncoder first.
URL-safe Base64
For JWTs, URLs, and filenames, swap + and / for - and _ and drop the padding:
// Encode to URL-safe Base64
function toBase64URL(str) {
return encodeBase64(str)
.replace(/\+/g, "-")
.replace(/\//g, "_")
.replace(/=+$/, ""); // remove padding
}
// Decode URL-safe Base64
function fromBase64URL(base64url) {
let base64 = base64url.replace(/-/g, "+").replace(/_/g, "/");
while (base64.length % 4) base64 += "="; // restore padding
return decodeBase64(base64);
}
Encode a file
In the browser, use the FileReader API to read a file as a Base64 data URI:
function fileToBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result); // data:mime;base64,...
reader.onerror = reject;
reader.readAsDataURL(file);
});
}
// Usage with a file input
input.addEventListener("change", async (e) => {
const dataUri = await fileToBase64(e.target.files[0]);
console.log(dataUri); // "data:image/png;base64,iVBOR..."
});
Frequently asked questions
How do I Base64 encode a string in JavaScript?
Use btoa("Hello") for ASCII, which returns "SGVsbG8=". For Unicode, encode to UTF-8 with new TextEncoder().encode(str) first, then btoa() the binary string.
How do I Base64 decode in JavaScript?
atob("SGVsbG8=") returns the binary string "Hello"; for Unicode, pass the bytes through new TextDecoder().decode().
Why does btoa() throw an InvalidCharacterError?
btoa() only accepts Latin-1 characters (0–255). Emoji and non-Latin text throw — encode to UTF-8 bytes with TextEncoder first.
How do I do URL-safe Base64?
Apply .replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "") to the standard output, then reverse it before atob().
Need image, file, or URL-safe modes?
The main base64.dev tool handles text, images, files, and URL-safe Base64 with auto-detect.
Open base64.dev →