Base64 Encoding Explained: When and How to Use It

If you have ever embedded an image directly in HTML, inspected a JWT token, or set up HTTP Basic Authentication, you have used Base64 encoding. It is one of those foundational concepts that developers encounter constantly but rarely think about in depth. Understanding how Base64 works — and more importantly, when and when not to use it — will make you a more effective developer.

Need to encode or decode Base64 right now? Try our Base64 Encoder & Decoder — it runs entirely in your browser with no data sent to any server.

What Is Base64 Encoding?

Base64 is a binary-to-text encoding scheme that represents binary data using a set of 64 printable ASCII characters. It was designed to solve a specific problem: how do you transmit binary data (images, files, raw bytes) through systems that only support text, such as email protocols (SMTP), JSON payloads, XML documents, and URL parameters?

The name "Base64" comes from the fact that it uses a 64-character alphabet to represent data. Compare this to our everyday decimal system (Base10, using digits 0-9) or hexadecimal (Base16, using 0-9 and A-F). Base64 uses a much larger character set, which makes it more space-efficient than hex encoding for representing binary data.

The 64-Character Alphabet

The standard Base64 alphabet (defined in RFC 4648) consists of:

  • A-Z — 26 uppercase letters (indices 0-25)
  • a-z — 26 lowercase letters (indices 26-51)
  • 0-9 — 10 digits (indices 52-61)
  • + — plus sign (index 62)
  • / — forward slash (index 63)
  • = — padding character (not part of the 64, used for alignment)

There is also a URL-safe variant called Base64url that replaces + with - and / with _ to avoid conflicts with URL-reserved characters. This variant is used in JWTs and other web-facing contexts.

How the Encoding Process Works

Base64 encoding processes input in groups of 3 bytes (24 bits) at a time, splitting each group into four 6-bit values. Each 6-bit value (0-63) maps to one character in the alphabet. Here is a step-by-step example encoding the string "Hi":

Input:    H         i
ASCII:    72        105
Binary:   01001000  01101001

Group into 6-bit chunks:
010010  000110  1001xx

Map to Base64 alphabet:
S       G       p

Since input was 2 bytes (not a multiple of 3), add one = padding:
Result:  SGk=

You can verify this yourself: btoa("Hi") in your browser console returns "SGk=".

Why Padding (=) Exists

Since Base64 processes input in 3-byte chunks but input lengths are not always divisible by 3, padding is needed to signal how many bytes were in the final chunk:

  • No padding — input length was divisible by 3
  • One = — final chunk had 2 bytes (one byte short)
  • Two == — final chunk had 1 byte (two bytes short)

Some modern implementations (like Base64url in JWTs) omit padding entirely because the decoder can calculate the original length from the encoded string length.

Common Use Cases for Base64

Data URIs (Inline Images and Fonts)

Data URIs let you embed files directly in HTML or CSS without a separate HTTP request. This is useful for small icons, SVGs, and critical images that should load immediately:

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEU..." alt="icon">

/* In CSS */
.icon {
  background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0...);
}

Convert images to data URIs instantly with our Image to Base64 Converter.

Email Attachments (MIME)

SMTP email was designed for 7-bit ASCII text. To send binary attachments (PDFs, images, zip files), email clients encode them as Base64 within MIME (Multipurpose Internet Mail Extensions) parts. When you attach a file to an email, your client Base64-encodes it behind the scenes, and the recipient's client decodes it.

JWT Tokens

JSON Web Tokens use Base64url encoding for their header and payload sections. A JWT consists of three parts separated by dots, and the first two parts are Base64url-encoded JSON:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.   // Base64url(header)
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ik...  // Base64url(payload)
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQ...  // signature

Decode and inspect JWTs with our JWT Decoder.

HTTP Basic Authentication

The HTTP Basic auth scheme sends credentials as a Base64-encoded string in the Authorization header:

// Encoding credentials
const credentials = btoa("username:password");
// Result: "dXNlcm5hbWU6cGFzc3dvcmQ="

// HTTP header
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=

Important: This is encoding, not encryption. Anyone can decode the credentials. Basic auth should only be used over HTTPS.

Embedding Binary Data in JSON and XML

JSON and XML are text formats that cannot contain raw binary bytes. When APIs need to include binary data (like a small image thumbnail or a cryptographic signature), Base64 encoding wraps the binary data in a text-safe string that fits cleanly into the payload.

Base64 vs. URL Encoding

Developers sometimes confuse Base64 encoding with URL encoding (percent-encoding), but they serve completely different purposes:

  • Base64 converts binary data into ASCII text. Use it when you need to represent binary data in a text-only context.
  • URL encoding converts unsafe URL characters into %XX hex sequences. Use it when you need to include special characters in URLs or form data.

They can be combined: if you put a Base64 string in a URL query parameter, the + and / characters need URL encoding, or you should use the Base64url variant instead. Explore the differences hands-on with our URL Encoder/Decoder.

Performance Considerations

Base64 encoding comes with trade-offs you should understand:

  • 33% size increase — every 3 bytes become 4 characters. A 30KB image becomes roughly 40KB as Base64. For large files, this overhead adds up quickly.
  • No browser caching — images embedded as data URIs cannot be cached independently. If the same icon appears on 50 pages, the browser re-downloads the Base64 string with each page instead of caching the image file once.
  • CPU cost — encoding and decoding require processing. In JavaScript, btoa() and atob() are fast for small strings but can block the main thread on large inputs. Use the FileReader API with readAsDataURL() for files.
  • Parsing overhead — Base64-encoded data in JSON makes the payload larger, increasing parse time. For large payloads, consider multipart responses or separate file endpoints.

When NOT to Use Base64

Base64 is the wrong tool in several common scenarios:

  • Security or obfuscation — Base64 is not encryption. It provides zero security. Use AES, RSA, or TLS for protecting data.
  • Large files — embedding a 500KB image as Base64 in your HTML adds 667KB to every page load and defeats browser caching. Serve it as a separate file.
  • API responses with large binary data — use multipart responses or return a URL to the file instead of embedding the file as Base64 in JSON.
  • Storing data in databases — most databases support binary/blob columns natively. Storing Base64 text uses 33% more space for no benefit.

Base64 in JavaScript: Quick Reference

// Encode a string to Base64
const encoded = btoa("Hello, World!");
// "SGVsbG8sIFdvcmxkIQ=="

// Decode Base64 back to a string
const decoded = atob("SGVsbG8sIFdvcmxkIQ==");
// "Hello, World!"

// Handle Unicode (btoa only supports Latin1)
const unicodeEncoded = btoa(unescape(encodeURIComponent("Caf\u00e9")));
const unicodeDecoded = decodeURIComponent(escape(atob(unicodeEncoded)));

// File to Base64 (using FileReader)
const reader = new FileReader();
reader.onload = () => console.log(reader.result); // data:image/png;base64,...
reader.readAsDataURL(file);

// Node.js
const b64 = Buffer.from("Hello").toString("base64");
const str = Buffer.from(b64, "base64").toString("utf-8");

Encode and Decode Base64 Now

Our Base64 Encoder & Decoder handles text and files, supports standard and URL-safe alphabets, and runs entirely in your browser. For encoding HTML entities, try the HTML Entity Encoder.

Frequently Asked Questions

No. Base64 is an encoding scheme, not encryption. It transforms binary data into a text-safe format, but anyone can decode it instantly. There is no key or secret involved. Never use Base64 to protect sensitive data like passwords or API keys. Use proper encryption algorithms like AES-256 or TLS for security.
Base64 represents every 3 bytes of binary data as 4 ASCII characters. Since 4/3 = 1.333, the encoded output is approximately 33% larger than the input. For example, a 30KB image becomes roughly 40KB when Base64-encoded. This overhead is the trade-off for being able to embed binary data in text-only contexts.
Base64 converts binary data into a text string using a 64-character alphabet (A-Z, a-z, 0-9, +, /). URL encoding (percent-encoding) replaces unsafe URL characters with %XX hex codes. They solve different problems: Base64 makes binary data text-safe, while URL encoding makes text URL-safe. Base64 strings often need URL encoding too if placed in URLs, which is why Base64url (RFC 4648) exists.
The = character is padding added to ensure the Base64 output length is a multiple of 4 characters. Since Base64 processes input in 3-byte chunks, if the input is not evenly divisible by 3, one or two = characters are appended. One byte remaining adds ==, two bytes remaining adds =. Some implementations like Base64url omit padding entirely since the decoder can infer the original length.
Avoid Base64 when the 33% size overhead matters, such as large files served over HTTP where the binary format is natively supported. Do not use it for security or obfuscation since it is trivially reversible. Avoid Base64-encoding large images inline in HTML or CSS, as it prevents browser caching and bloats the document. For files over a few KB, a separate HTTP request with proper caching is usually better.