Developer ToolsBy Sam Holloway··Updated ·10 min read

What Is Base64 Encoding? A Plain-English Explanation

What is Base64 encoding? A plain-English guide covering how it works, where it appears, JavaScript code examples, JWTs, and when not to use it.

You have almost certainly encountered Base64 even if you have never heard the term. The long string of letters, numbers, slashes, and plus signs that appears in a data URI, in the Authorization header of an API request, or inside a JSON Web Token is usually Base64-encoded data. What is Base64 encoding exactly? Understanding what it is and why it exists makes a surprising number of web development concepts click into place.

The problem Base64 solves

Computers store everything as binary: sequences of 1s and 0s. Transmitting arbitrary binary data (images, executables, encrypted payloads) over systems designed for text creates problems. Early email protocols, HTTP headers, URLs, and JSON are all text-based systems that either cannot carry raw binary at all or interpret certain byte values as control characters with special meaning. A single byte with the value 0x00, for example, terminates a C string: inserting it into a text field causes the rest of the data to be silently dropped.

Base64 solves this by re-encoding binary data using only 64 safe printable ASCII characters: A-Z, a-z, 0-9, +, and /. Any binary data, regardless of what bytes it contains, can be represented as a string of these safe characters that will survive unmodified through any text-based system.

How Base64 encoding actually works

The algorithm takes three bytes of binary data (24 bits) at a time and splits them into four groups of 6 bits each. Each 6-bit group (which can represent values 0 to 63) is mapped to one of the 64 safe characters using a lookup table. The result is that every 3 bytes of input become 4 characters of output: a size increase of exactly 33 percent.

If the input length is not a multiple of three, the output is padded with one or two = characters to maintain the 4-character block structure. This padding is why Base64 strings often end with one or two equals signs.

Base64 in JavaScript: encoding and decoding

Every modern browser and Node.js 16+ includes two built-in functions for Base64: btoa() to encode and atob() to decode. The names stand for 'binary to ASCII' and 'ASCII to binary'. No library import is needed.

javascript
// Encode a string to Base64
const encoded = btoa("Hello, world!");
console.log(encoded); // "SGVsbG8sIHdvcmxkIQ=="

// Decode Base64 back to a string
const decoded = atob("SGVsbG8sIHdvcmxkIQ==");
console.log(decoded); // "Hello, world!"

// Encode arbitrary bytes (e.g. from a Uint8Array)
const bytes = new Uint8Array([72, 101, 108, 108, 111]);
const fromBytes = btoa(String.fromCharCode(...bytes));
console.log(fromBytes); // "SGVsbG8="

One important limitation: btoa() only accepts strings where every character has a code point of 255 or below (Latin-1). If you pass a string containing emoji or accented characters outside that range, it throws a character out of range error. The standard workaround is to encode the string as UTF-8 bytes first using encodeURIComponent, then decode the percent-encoded bytes before passing to btoa(). In modern environments, the TextEncoder API is a cleaner alternative for handling arbitrary Unicode.

Base64URL: the URL-safe variant used in JWTs

Standard Base64 uses two characters that have special meaning in URLs: the plus sign (+) is interpreted as a space in query strings, and the forward slash (/) is a path separator. This makes standard Base64 output unsafe to embed directly in a URL or HTTP header without additional encoding. Base64URL solves this by replacing + with - (hyphen) and / with _ (underscore), and by omitting the trailing = padding characters entirely.

JSON Web Tokens use Base64URL throughout. A JWT is three Base64URL-encoded segments separated by dots: the header, the payload, and the signature. Because Base64URL is reversible without a key, anyone who has the token can decode the header and payload and read their contents. The signature section is what prevents tampering, not the encoding. You can decode a JWT header in any browser console without any library:

javascript
// A real JWT looks like: xxxxx.yyyyy.zzzzz
const token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIn0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c";

const [headerB64, payloadB64] = token.split(".");

// Convert Base64URL to standard Base64 before decoding
function fromBase64Url(b64url) {
  return b64url.replace(/-/g, "+").replace(/_/g, "/");
}

const header = JSON.parse(atob(fromBase64Url(headerB64)));
console.log(header);
// { alg: "HS256", typ: "JWT" }

const payload = JSON.parse(atob(fromBase64Url(payloadB64)));
console.log(payload);
// { sub: "1234567890", name: "John Doe" }

Encoding files in Node.js

In Node.js, the Buffer class handles Base64 encoding and decoding natively. This is the standard approach for encoding file contents to Base64 before embedding them in an API response, an email attachment, or a JSON payload. The same Buffer API decodes Base64 back to the original binary without any external library.

javascript
const fs = require("fs");

// Read a file and encode it to Base64
const fileBuffer = fs.readFileSync("image.png");
const base64String = fileBuffer.toString("base64");
console.log(base64String); // "iVBORw0KGgoAAAANSUhEUgAA..."

// Decode a Base64 string back to a file
const decoded = Buffer.from(base64String, "base64");
fs.writeFileSync("output.png", decoded);

// In modern Node.js you can also use:
// Buffer.from(base64String, "base64").toString("utf8")
// for text content (e.g. a Base64-encoded JSON string)

Where Base64 appears in practice

  • Email attachments: MIME encoding uses Base64 to embed binary files (images, PDFs, executables) inside the plain-text body of an email. This is why forwarded emails sometimes grow in size.
  • Data URIs: CSS and HTML can embed images directly in the source using data:image/png;base64,[encoded string], eliminating a separate HTTP request for small images such as icons or loading spinners.
  • HTTP Basic Authentication: Credentials in the Authorization: Basic header are Base64-encoded as username:password. This is not encryption: the credentials are fully recoverable by anyone who intercepts the header.
  • JSON Web Tokens (JWT): The header, payload, and signature sections of a JWT are Base64URL-encoded. The encoding makes the token URL-safe and human-readable when decoded, but provides no security on its own.
  • API responses: Many APIs return binary content (thumbnails, generated images, audio clips) as Base64 strings inside JSON payloads, since JSON cannot natively carry binary data.
  • Cryptographic keys and certificates: PEM-formatted certificates are Base64-encoded DER data wrapped in -----BEGIN CERTIFICATE----- headers. The .pem files you use with TLS servers are Base64 inside.
  • CSS background images: Small SVGs and pixel images are often embedded directly in stylesheets as Base64 data URIs to reduce the number of network requests on initial page load.

Base64 is encoding, not encryption

This is the most important distinction to understand. Base64 provides zero security. Anyone who encounters a Base64 string can decode it in seconds using any online tool or a single line of code. It is not a form of obfuscation, it is not a form of hashing, and it is not a substitute for encryption. It exists purely to make binary data safe for text-based transmission, not to protect it.

Using Base64 to hide a password, API key, or secret in a configuration file or HTTP request is a common and dangerous mistake. The encoding provides no protection: it just adds a trivial decoding step that anyone who recognises the format will immediately reverse. Secrets belong in environment variables or a proper secrets manager, not Base64-encoded strings.

A quick way to check if a suspicious string is Base64: paste it into the browser console and run atob(theString). If it returns readable text or binary-looking output rather than an error, it was Base64-encoded.

When not to use Base64

The 33 percent size overhead is real and compounds in API responses. Sending a 1 MB image as a Base64 string in a JSON response results in a 1.37 MB payload, which affects bandwidth, parsing time, and memory usage on the client. For large binary files, a separate URL reference is almost always more efficient than inline Base64. The data URI technique is appropriate for small images (icons, loading spinners) where the HTTP request overhead outweighs the size penalty: typically assets below 5 KB.

Base64 is also a poor choice when you need to stream large files. Because the entire Base64 string must be assembled before it can be parsed as JSON, there is no streaming benefit. For video, audio, or large document downloads, serve the binary file directly from a URL and let the browser or HTTP client handle range requests and progressive download.

How to encode and decode Base64 online

When debugging API responses, you frequently need to quickly decode a Base64 string to see what it contains, or encode a test payload to include in a request. Running a Node.js script or opening a browser console works, but a dedicated tool is faster for repetitive work.

The Base64 Encoder / Decoder tool at AlteredIdea handles text and file input, encodes and decodes in both standard Base64 and Base64URL mode, and runs entirely in your browser. Nothing is uploaded to a server: useful when the string you are inspecting contains credentials or sensitive data from an API response you are debugging.

AlteredIdea's Base64 Encoder / Decoder converts text or files to Base64 and back, entirely in your browser. Supports both standard Base64 and Base64URL mode. Useful for decoding JWT payloads, constructing data URIs, and debugging API responses that return binary content as strings.

S

Sam Holloway

Sam is a technical writer and developer who has spent over a decade building web tools and writing about software, security, and the web platform. He focuses on making complex topics genuinely useful for working developers and non-technical users alike.

Try it yourself

Base64 Encoder / Decoder

Free, browser-based: your files never leave your device.

Open tool