A complete guide to working with Base64 in JavaScript — browser APIs, Node.js, handling Unicode, and binary data.
// Encode
const encoded = btoa("Hello, World!");
console.log(encoded); // "SGVsbG8sIFdvcmxkIQ=="
// Decode
const decoded = atob("SGVsbG8sIFdvcmxkIQ==");
console.log(decoded); // "Hello, World!"
btoa() only handles Latin-1 characters. Emojis throw InvalidCharacterError:
btoa("Hello World!"); // OK
btoa("Hello \u{1F44B}"); // Throws!
// Fix: encode to UTF-8 bytes first
function encodeUnicode(str) {
const bytes = new TextEncoder().encode(str);
const binStr = Array.from(bytes, (b) => String.fromCodePoint(b)).join('');
return btoa(binStr);
}
// Encode
const encoded = Buffer.from('Hello, World!').toString('base64');
// Decode
const decoded = Buffer.from(encoded, 'base64').toString('utf8');
// Base64URL
const url = Buffer.from('Hello+/World').toString('base64url');
function toBase64URL(base64) {
return base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
}
function fromBase64URL(b64url) {
const padded = b64url + '=='.slice((b64url.length + 3) % 4);
return padded.replace(/-/g, '+').replace(/_/g, '/');
}
// Browser: FileReader
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => {
const base64 = reader.result.split(',')[1]; // Remove data:...;base64, prefix
};
// Node.js
const fs = require('fs');
const base64 = fs.readFileSync('image.png').toString('base64');