Base64 Encode & Decode in JavaScript
JavaScript provides built-in functions for Base64 encoding and decoding in browsers (btoa / atob), and the Buffer class in Node.js. This guide covers both environments, Unicode handling, and practical patterns like data URIs and HTTP Authorization headers.
Base64 encode in JavaScript (browser)
btoa() encodes a string to Base64. It only accepts ASCII/Latin-1 strings.
btoa('Hello') // "SGVsbG8="
btoa('Hello World') // "SGVsbG8gV29ybGQ="
btoa('1 + 1 = 2') // "MSArIDEgPSAy"Base64 decode in JavaScript (browser)
atob() decodes a Base64 string back to plain text:
atob('SGVsbG8=') // "Hello"
atob('SGVsbG8gV29ybGQ=') // "Hello World"Handling Unicode with btoa/atob
btoa() throws a InvalidCharacterError for characters outside Latin-1 (code points above 255). To encode Unicode, first convert to UTF-8 bytes:
// Encode Unicode to Base64
function encodeBase64(str) {
return btoa(
encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, (_, p1) =>
String.fromCharCode(parseInt(p1, 16))
)
)
}
// Decode Base64 to Unicode
function decodeBase64(str) {
return decodeURIComponent(
Array.from(atob(str))
.map(c => '%' + c.charCodeAt(0).toString(16).padStart(2, '0'))
.join('')
)
}
encodeBase64('こんにちは') // "44GT44KT44Gr44Gh44Gv"
decodeBase64('44GT44KT44Gr44Gh44Gv') // "こんにちは"In modern browsers you can also use TextEncoder and TextDecoder:
// Encode string to Base64 using TextEncoder
function toBase64(str) {
const bytes = new TextEncoder().encode(str)
const binary = Array.from(bytes, b => String.fromCharCode(b)).join('')
return btoa(binary)
}
// Decode Base64 to string using TextDecoder
function fromBase64(base64) {
const binary = atob(base64)
const bytes = Uint8Array.from(binary, c => c.charCodeAt(0))
return new TextDecoder().decode(bytes)
}
toBase64('Hello 🌍') // "SGVsbG8g8J+MjQ=="
fromBase64('SGVsbG8g8J+MjQ==') // "Hello 🌍"Base64 in Node.js
Node.js uses the Buffer class for Base64 operations. No import needed:
// Encode to Base64
const encoded = Buffer.from('Hello World').toString('base64')
// "SGVsbG8gV29ybGQ="
// Decode from Base64
const decoded = Buffer.from('SGVsbG8gV29ybGQ=', 'base64').toString('utf8')
// "Hello World"
// Unicode works by default — Buffer handles UTF-8
Buffer.from('こんにちは').toString('base64')
// "44GT44KT44Gr44Gh44Gv"
Buffer.from('44GT44KT44Gr44Gh44Gv', 'base64').toString('utf8')
// "こんにちは"Base64url (URL-safe Base64)
Standard Base64 uses + and /, which have special meaning in URLs. Base64url replaces them with - and _ and omits padding. JWTs use Base64url for their header and payload:
// Standard Base64 → Base64url
function toBase64Url(str) {
return btoa(str).replace(/+/g, '-').replace(///g, '_').replace(/=/g, '')
}
// Base64url → standard Base64
function fromBase64Url(base64url) {
const padded = base64url.replace(/-/g, '+').replace(/_/g, '/') +
'=='.slice(0, (4 - base64url.length % 4) % 4)
return atob(padded)
}
// Node.js
Buffer.from(str).toString('base64url') // encode
Buffer.from(str, 'base64url').toString() // decodeData URIs with Base64
Data URIs embed file content directly in HTML or CSS using Base64:
// Encode a local file as a data URI (browser with File API)
async function fileToDataUri(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.onload = () => resolve(reader.result)
reader.onerror = reject
reader.readAsDataURL(file)
})
}
// Create a small red dot PNG as a data URI (Node.js)
const pngBuffer = fs.readFileSync('dot.png')
const dataUri = 'data:image/png;base64,' + pngBuffer.toString('base64')
// "data:image/png;base64,iVBORw0KGgo..."HTTP Basic Auth header
HTTP Basic Authentication encodes credentials as Base64 in the Authorization header:
// Browser
const credentials = btoa('username:password')
const headers = { 'Authorization': 'Basic ' + credentials }
// Node.js
const credentials = Buffer.from('username:password').toString('base64')
const headers = { 'Authorization': 'Basic ' + credentials }Encode or decode Base64 online
Use the Base64 Encoder to encode any text instantly, or the Base64 Decoder to decode a Base64 string. Both handle Unicode and run entirely in your browser.