BASE64
Decodificar & Codificar
← Guides· 4 min read

Base64 Encode & Decode in JavaScript

Using btoa(), atob(), and Buffer in the browser and Node.js — including Unicode handling and common pitfalls.

Browser: btoa() and atob()

Modern browsers have two built-in functions for Base64:

  • btoa(str) — binary to ASCII — encodes to Base64
  • atob(str) — ASCII to binary — decodes from Base64
// Encode
const encoded = btoa("Hello, World!");
console.log(encoded); // SGVsbG8sIFdvcmxkIQ==

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

The Unicode Problem with btoa()

btoa() only handles Latin1 characters (byte values 0–255). Passing a string with emoji or multi-byte Unicode characters throws InvalidCharacterError:

// ❌ Throws error
btoa("Hello 🌍"); // InvalidCharacterError

// ✅ Fix: encode URI components first
btoa(unescape(encodeURIComponent("Hello 🌍")));
// → "SGVsbG8g8J+MjQ=="

// ✅ Decode back
decodeURIComponent(escape(atob("SGVsbG8g8J+MjQ==")));
// → "Hello 🌍"

Node.js: Buffer (Recommended)

In Node.js, Buffer handles Unicode natively and is the preferred approach:

// Encode
const encoded = Buffer.from("Hello 🌍", "utf8").toString("base64");
console.log(encoded); // SGVsbG8g8J+MjQ==

// Decode
const decoded = Buffer.from("SGVsbG8g8J+MjQ==", "base64").toString("utf8");
console.log(decoded); // Hello 🌍

// Encode a file
const fs = require("fs");
const fileBuffer = fs.readFileSync("./image.png");
const base64Image = fileBuffer.toString("base64");

// Decode back to file
fs.writeFileSync("./output.png", Buffer.from(base64Image, "base64"));

URL-Safe Base64 in JavaScript

Standard Base64 uses + and / which must be percent-encoded in URLs. Convert to URL-safe format:

// Standard → URL-safe
const urlSafe = btoa("Hello+World").replace(/+/g, "-").replace(///g, "_").replace(/=/g, "");

// URL-safe → Standard (for decoding)
function fromUrlSafe(str) {
  return str.replace(/-/g, "+").replace(/_/g, "/") + "==".slice((str.length % 4) || 4);
}
const decoded = atob(fromUrlSafe(urlSafe));

// Node.js URL-safe encode
const urlSafeNode = Buffer.from("Hello+World").toString("base64url");
// → "SGVsbG8rV29ybGQ"  (no padding, - and _ instead of + and /)

Decoding a JWT Payload

function decodeJwtPayload(token) {
  const payload = token.split(".")[1]; // Get middle section
  // Convert URL-safe Base64 to standard
  const standard = payload.replace(/-/g, "+").replace(/_/g, "/");
  // Decode and parse JSON
  return JSON.parse(atob(standard));
}

const jwt = "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiYWxpY2UiLCJyb2xlIjoiYWRtaW4ifQ.xxx";
console.log(decodeJwtPayload(jwt));
// → { user: "alice", role: "admin" }

Quick Reference

EnvironmentEncodeDecode
Browser (ASCII only)btoa(str)atob(str)
Browser (Unicode)btoa(unescape(encodeURIComponent(str)))decodeURIComponent(escape(atob(str)))
Node.jsBuffer.from(str).toString('base64')Buffer.from(b64, 'base64').toString('utf8')
Node.js URL-safeBuffer.from(str).toString('base64url')Buffer.from(b64, 'base64url').toString('utf8')

Test Base64 online

Encode or decode any Base64 string instantly in your browser — no code required.

Open Base64 Converter →

Frequently Asked Questions

How do I encode a string to Base64 in JavaScript?

Use btoa() in the browser: const encoded = btoa('Hello'); // → SGVsbG8=. In Node.js, use Buffer.from('Hello').toString('base64').

Why does btoa() throw an error with Unicode characters?

btoa() only handles Latin1 characters (code points 0-255). For Unicode strings, use: btoa(unescape(encodeURIComponent(str))). In Node.js, use Buffer.from(str, 'utf8').toString('base64') which handles Unicode natively.

How do I decode Base64 in JavaScript?

Use atob() in the browser: const decoded = atob('SGVsbG8='); // → Hello. In Node.js, use Buffer.from('SGVsbG8=', 'base64').toString('utf8').