How to Encode Base64 in JavaScript

Learn how to encode and decode Base64 in JavaScript with btoa, atob, and modern alternatives. Complete tutorial with code examples for text, files, and images.

How to Encode Base64 in JavaScript

Base64 encoding is essential for embedding images, transmitting binary data, and working with APIs. JavaScript provides built-in methods for Base64 operations. This tutorial covers encoding, decoding, and handling special cases like Unicode text and files.

Method 1: Built-in btoa() and atob()

The simplest way to encode Base64 in browsers:

// Encode to Base64
const text = 'Hello, World!';
const encoded = btoa(text);
console.log(encoded);
// "SGVsbG8sIFdvcmxkIQ=="

// Decode from Base64 const decoded = atob(encoded); console.log(decoded); // "Hello, World!"

What Do btoa and atob Mean?

  • btoa: "Binary to ASCII" (encode)
  • atob: "ASCII to Binary" (decode)

Browser Support

| Browser | Support | |---------|---------| | Chrome | ✅ All versions | | Firefox | ✅ All versions | | Safari | ✅ All versions | | Edge | ✅ All versions | | Node.js | ❌ Not available |

Method 2: Buffer API (Node.js)

For server-side JavaScript:

// Encode
const text = 'Hello, World!';
const encoded = Buffer.from(text, 'utf-8').toString('base64');
console.log(encoded);
// "SGVsbG8sIFdvcmxkIQ=="

// Decode const decoded = Buffer.from(encoded, 'base64').toString('utf-8'); console.log(decoded); // "Hello, World!"

Universal Function (Browser + Node.js)

function encodeBase64(str) {
  if (typeof Buffer !== 'undefined') {
    // Node.js
    return Buffer.from(str, 'utf-8').toString('base64');
  } else {
    // Browser
    return btoa(unescape(encodeURIComponent(str)));
  }
}

function decodeBase64(str) { if (typeof Buffer !== 'undefined') { // Node.js return Buffer.from(str, 'base64').toString('utf-8'); } else { // Browser return decodeURIComponent(escape(atob(str))); } }

Handling Unicode Characters

The built-in btoa() only works with ASCII characters. For Unicode:

// ❌ This fails with non-ASCII characters
btoa('你好'); // Error

// ✅ Use this for Unicode const text = '你好,世界!'; const encoded = btoa(unescape(encodeURIComponent(text))); console.log(encoded); // "5L2g5aW977yB5LiW55WMISIK

// Decode const decoded = decodeURIComponent(escape(atob(encoded))); console.log(decoded); // "你好,世界!"

Why This Works

1. encodeURIComponent() converts Unicode to UTF-8 percent-encoded 2. unescape() converts percent-encoded to binary string 3. btoa() encodes binary string to Base64

Encoding Files and Images

File to Base64

function fileToBase64(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => resolve(reader.result);
    reader.onerror = error => reject(error);
  });
}

// Usage const input = document.querySelector('input[type="file"]'); input.addEventListener('change', async (e) => { const file = e.target.files[0]; const base64 = await fileToBase64(file); console.log(base64); // "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..." });

Image URL to Base64

async function imageUrlToBase64(url) {
  const response = await fetch(url);
  const blob = await response.blob();

return new Promise((resolve, reject) => { const reader = new FileReader(); reader.readAsDataURL(blob); reader.onload = () => resolve(reader.result); reader.onerror = error => reject(error); }); }

// Usage const base64 = await imageUrlToBase64('https://example.com/image.png'); console.log(base64);

Base64 to Blob (for Download)

function base64ToBlob(base64, mimeType) {
  const byteCharacters = atob(base64.split(',')[1] || base64);
  const byteNumbers = new Array(byteCharacters.length);

for (let i = 0; i < byteCharacters.length; i++) { byteNumbers[i] = byteCharacters.charCodeAt(i); }

const byteArray = new Uint8Array(byteNumbers); return new Blob([byteArray], { type: mimeType }); }

// Usage const blob = base64ToBlob('data:image/png;base64,iVBORw0KGgoAAA...', 'image/png');

// Download const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'image.png'; a.click(); URL.revokeObjectURL(url);

URL-Safe Base64 Encoding

Standard Base64 uses + and / which aren't URL-safe:

function base64UrlEncode(str) {
  return btoa(str)
    .replace(/\+/g, '-')
    .replace(/\//g, '_')
    .replace(/=/g, '');
}

function base64UrlDecode(str) { // Add padding if needed const padding = '='.repeat((4 - str.length % 4) % 4); const base64 = str.replace(/-/g, '+').replace(/_/g, '/') + padding; return atob(base64); }

// Usage const urlSafe = base64UrlEncode('Hello+World/Test'); console.log(urlSafe); // "SGVsbG8rV29ybGQvVGVzdA" (no + or /)

Complete Base64 Utility Class

class Base64Utils {
  // Encode text to Base64
  static encode(text) {
    if (typeof Buffer !== 'undefined') {
      return Buffer.from(text, 'utf-8').toString('base64');
    }
    return btoa(unescape(encodeURIComponent(text)));
  }

// Decode Base64 to text static decode(base64) { if (typeof Buffer !== 'undefined') { return Buffer.from(base64, 'base64').toString('utf-8'); } return decodeURIComponent(escape(atob(base64))); }

// URL-safe encoding static encodeUrlSafe(text) { return this.encode(text) .replace(/\+/g, '-') .replace(/\//g, '_') .replace(/=/g, ''); }

// URL-safe decoding static decodeUrlSafe(base64) { const padding = '='.repeat((4 - base64.length % 4) % 4); const standard = base64 .replace(/-/g, '+') .replace(/_/g, '/') + padding; return this.decode(standard); }

// File to Base64 static fileToBase64(file) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.readAsDataURL(file); reader.onload = () => resolve(reader.result); reader.onerror = error => reject(error); }); }

// Base64 to Blob static base64ToBlob(base64, mimeType) { const data = base64.includes(',') ? base64.split(',')[1] : base64; const byteCharacters = atob(data); const byteNumbers = new Array(byteCharacters.length);

for (let i = 0; i < byteCharacters.length; i++) { byteNumbers[i] = byteCharacters.charCodeAt(i); }

return new Blob([new Uint8Array(byteNumbers)], { type: mimeType }); } }

// Usage const encoded = Base64Utils.encode('Hello, 世界!'); const decoded = Base64Utils.decode(encoded); const urlSafe = Base64Utils.encodeUrlSafe('Hello+World');

Common Use Cases

Embedding Images in HTML

// Create data URL for inline image
const img = document.createElement('img');
img.src = await Base64Utils.fileToBase64(fileInput.files[0]);
document.body.appendChild(img);

Storing Binary Data in JSON

const payload = {
  filename: 'document.pdf',
  mimeType: 'application/pdf',
  data: Base64Utils.encode(fileContent)
};

// Send via API fetch('/api/upload', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) });

Basic Authentication Header

const credentials = 'username:password';
const encoded = Base64Utils.encode(credentials);
const headers = {
  'Authorization': Basic ${encoded}
};

Try It Online

Need to encode Base64 quickly? Use our Base64 Encoder for instant encoding with file support and URL-safe options.

Conclusion

For simple ASCII encoding in browsers, btoa() works well. For Unicode support and Node.js, use the Buffer approach or the utility class above. Always handle Unicode properly to avoid encoding errors.

For related topics, see How to Decode a JWT Token which uses Base64url encoding.

---

Related Tools:

🚀 Deploy Your Own Tools — Recommended Hosting

Want to self-host or build your own developer tools? These are the platforms we use:

🌐
Hostinger
Web Hosting from $2.99/mo
💧
DigitalOcean
$200 Free Credit for New Users
🔑
Namecheap
Domains from $0.99/yr

* Affiliate links — we may earn a commission at no extra cost to you.

❤️ Support Independent Development

Love these free tools? Help keep them ad-free forever with a small contribution.

🛠️

DevKits Offline Pack

82 个开发者工具离线版

👥 Join 200+ supporters

Pay What You Want Support →
📝

SEO Content Pack

100 篇开发者文章模板

👥 Join 200+ supporters

Support $1+ Support →
💎

Airdrop Hunter Guide

2026 空投狩猎完整指南

👥 Join 200+ supporters

Support $1+ Support →

💙 Your support keeps these tools free for everyone