Base64 Encoding in JavaScript — Complete Guide with Examples
Base64 is a binary-to-text encoding scheme that converts binary data into a string of 64 printable ASCII characters. In JavaScript, btoa() and atob() are the built-in browser functions for Base64 encoding and decoding. This guide covers everything from the basics to handling Unicode, Node.js Buffers, and URL-safe variants.
btoa — encode to Base64
btoa('Hello, World!');
// → 'SGVsbG8sIFdvcmxkIQ=='
btoa('admin:password123');
// → 'YWRtaW46cGFzc3dvcmQxMjM='
// Used for HTTP Basic Auth headersatob — decode from Base64
atob('SGVsbG8sIFdvcmxkIQ==');
// → 'Hello, World!'The Unicode problem — and how to fix it
btoa() only accepts Latin-1 characters. Passing multi-byte characters (emoji, accented letters, Indian scripts) throws a DOMException. Fix it by encoding to UTF-8 bytes first:
// Safe Base64 encode for any Unicode string
function toBase64(str) {
const bytes = new TextEncoder().encode(str);
let binary = '';
for (const b of bytes) binary += String.fromCharCode(b);
return btoa(binary);
}
// Safe Base64 decode
function fromBase64(b64) {
const binary = atob(b64);
const bytes = Uint8Array.from(binary, c => c.charCodeAt(0));
return new TextDecoder().decode(bytes);
}
toBase64('नमस्ते 🙏');
// works correctlyBase64 in Node.js using Buffer
// Encode
Buffer.from('Hello, World!').toString('base64');
// → 'SGVsbG8sIFdvcmxkIQ=='
// Decode
Buffer.from('SGVsbG8sIFdvcmxkIQ==', 'base64').toString('utf8');
// → 'Hello, World!'
// Read a file and encode it
import fs from 'fs';
const fileData = fs.readFileSync('./image.png');
const base64Image = fileData.toString('base64');URL-safe Base64
Standard Base64 uses + and /, which must be percent-encoded in URLs. URL-safe Base64 replaces them:
function toBase64Url(str) {
return toBase64(str)
.replace(/+/g, '-')
.replace(///g, '_')
.replace(/=+$/, ''); // strip padding
}
function fromBase64Url(b64url) {
const b64 = b64url
.replace(/-/g, '+')
.replace(/_/g, '/');
return fromBase64(b64);
}Common real-world use cases
- HTTP Basic Auth —
Authorization: Basic {btoa('user:pass')} - Data URIs — embed images inline in HTML/CSS:
src="data:image/png;base64,{base64Data}" - JWT payloads — the middle section of a JWT is Base64Url-encoded JSON
- Email attachments — MIME encodes binary attachments as Base64
- Passing binary in JSON APIs — encode file bytes as a Base64 string field
Frequently Asked Questions
btoa() only accepts characters in the Latin-1 range (code points 0-255). Any string containing emoji, accented letters outside Latin-1, or non-Latin scripts like Hindi or Chinese throws a DOMException. Encode the string to UTF-8 bytes with TextEncoder first, then pass the resulting byte string to btoa().
In Node.js, prefer Buffer.from(str).toString('base64') and Buffer.from(b64, 'base64').toString('utf8') — Buffer handles Unicode correctly out of the box, with no manual TextEncoder workaround needed. Reach for btoa()/atob() only in browser code, where Buffer is not available.
Any time the encoded value will be placed inside a URL, query parameter, or filename — standard Base64's + and / characters can be misread as URL structure. URL-safe Base64 (Base64Url) replaces them with - and _ and drops padding, which is exactly what JWTs use for their header and payload segments.
Try it instantly in your browser
Use our free Base64 Encoder / Decoder to encode or decode any string instantly. Supports Unicode and URL-safe mode — no data uploaded.