Base64 vs URL Encoding — Key Differences Explained

Both Base64 and URL encoding (percent-encoding) convert data into a safe text format — but they solve very different problems and produce very different output. Confusing the two is a common source of bugs. This guide explains each one, when to use it, and how the output compares.

The core difference

  • Base64 — converts binary data (bytes) into a fixed 64-character alphabet (A–Z, a–z, 0–9, +, /). Used to safely represent binary data as text.
  • URL encoding (percent-encoding) — encodes characters that have special meaning in a URL (like &, =, spaces) so they are treated as literal data. Used to make text safe for inclusion in a URL.

Side-by-side comparison

PropertyBase64URL Encoding
PurposeBinary data → textText → URL-safe text
Output charactersA–Z a–z 0–9 + / =Original + %XX sequences
Size increase~33%Varies (1–3x for special chars)
ReversibleYesYes
Works in URLsPartially (+ and / clash)Yes — that is the point
Handles binaryYesNo (text only)
JS encode fnbtoa() / Buffer.from()encodeURIComponent()
JS decode fnatob() / Buffer.from()decodeURIComponent()

Encoding the same string — output comparison

const input = 'hello world & price=₹500';

// Base64
btoa(input);
// Error! btoa() can't handle ₹ (multi-byte)
// Correct approach:
Buffer.from(input).toString('base64');
// → 'aGVsbG8gd29ybGQgJiBwcmljZT3igrk1MDA='

// URL encoding
encodeURIComponent(input);
// → 'hello%20world%20%26%20price%3D%E2%82%B9500'

When to use Base64

  • Embedding images, fonts, or files as inline data URIs in HTML/CSS
  • Encoding binary file content for inclusion in a JSON field
  • HTTP Basic Authentication credentials
  • The payload and header sections of a JWT token
  • Email MIME attachments

When to use URL encoding

  • Encoding user search input for a query string parameter
  • Including a redirect URL as a query parameter
  • Encoding form data submitted via application/x-www-form-urlencoded
  • Making REST API parameters with spaces or special characters safe
  • Encoding non-ASCII filenames in Content-Disposition headers

URL-safe Base64 — bridging the gap

When you need Base64 inside a URL (e.g., in a JWT), use URL-safe Base64 which replaces +- and /_ and removes padding = signs. This avoids conflicts with URL-structural characters while keeping the Base64 encoding scheme.

The mistake: mixing the two without realizing it

The most common bug is passing raw Base64 output straight into a URL — as a query parameter, a path segment, or a redirect target — without accounting for the fact that standard Base64's + and / characters are also meaningful to a URL parser:

const token = Buffer.from('user:1234+admin/root').toString('base64');
// 'dXNlcjoxMjM0K2FkbWluL3Jvb3Q='

// WRONG — a bare '+' in a URL is decoded as a space, and '/'
// can be read as a path separator by naive routers
const badUrl = `/verify?token=${token}`;

// RIGHT — either percent-encode the Base64 output...
const okUrl = `/verify?token=${encodeURIComponent(token)}`;

// ...or generate URL-safe Base64 (Base64Url) in the first place, which
// has no '+', '/', or padding '=' to begin with
const urlSafeToken = token.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
const bestUrl = `/verify?token=${urlSafeToken}`;

Frequently Asked Questions

Can I put Base64 output directly into a URL?

Not safely with standard Base64 — it can contain + and /, both of which have special meaning in a URL. Either percent-encode the Base64 string with encodeURIComponent first, or use URL-safe Base64 (Base64Url), which replaces + with -, / with _, and drops padding = characters.

Is Base64 shorter or longer than URL encoding for the same input?

It depends on the input. Base64 always adds a fixed ~33% to any input, binary or text. URL encoding only expands the specific characters that need escaping — plain alphanumeric text barely grows, while text full of spaces or symbols can expand to 3x per character (%XX per byte). For mostly-ASCII text with a few special characters, URL encoding is usually shorter.

Why does a JWT use Base64 instead of URL encoding for its payload?

A JWT payload is arbitrary JSON, and URL encoding only escapes special characters — it does not compact or structure binary-safe data the way Base64 does. JWTs use Base64Url (the URL-safe variant of Base64) specifically so the token can be embedded directly in a URL or header without further encoding.

Try both tools in your browser

Use our Base64 Encoder / Decoder or URL Encoder / Decoder to test encoding instantly — both tools run entirely in your browser with no data uploaded.

Related articles