Encodings / Guides

Base64 URL

Standard Base64 with two characters swapped and the padding removed. Use it whenever the encoded value will sit in a URL, a filename, or anywhere + and / have other meanings.

The two-character difference

Standard Base64 (RFC 4648 §4)Base64 URL (RFC 4648 §5)
Index 62+-
Index 63/_
Padding= required to multiple of 4Usually omitted
Indices 0–61A–Z a–z 0–9Same

Convert by hand

Standard → URL:

standard
  .replace(/\+/g, "-")
  .replace(/\//g, "_")
  .replace(/=+$/, "");

URL → Standard (re-pad before decoding):

const padded = url
  .replace(/-/g, "+")
  .replace(/_/g, "/");
const repadded = padded + "=".repeat((4 - padded.length % 4) % 4);

Where you'll see it

Common mistakes

Forgetting to re-pad before decoding

Standard Base64 decoders require padding. If you call atob() directly on a Base64 URL string of length 22 (e.g., a JWT segment), you'll get InvalidCharacterError. Either re-pad (above) or use a library that accepts unpadded input.

Treating it as URL-encoded Base64

Don't encodeURIComponent a Base64 URL string — it's already URL-safe. Doing so produces things like %3D%3D from a literal ==, and now you have to decode twice on the other end.

Mixing alphabets

Generating with btoa (standard) and decoding with a Base64-URL-only function will silently fail on values containing a + or /. Pick one alphabet at the boundary and stick with it.

Native support across languages

LanguageStandardBase64 URL
JavaScript (browser)btoa / atobNone — convert manually or use a lib
Node.jsBuffer.from(s, "base64")Buffer.from(s, "base64url") (Node 16+)
Pythonbase64.b64encode/decodebase64.urlsafe_b64encode/decode
Gobase64.StdEncodingbase64.URLEncoding / RawURLEncoding
JavaBase64.getEncoder()Base64.getUrlEncoder().withoutPadding()
Rust (base64)STANDARDURL_SAFE_NO_PAD

Reference

FAQ

Is Base64 URL the same as Base64?

Same encoding (6-bit groups → ASCII), different alphabet. Standard Base64 uses A-Z a-z 0-9 + /. Base64 URL substitutes - for + and _ for /, both of which are URL- and filename-safe. Padding (=) is usually omitted because it conflicts with query-string syntax.

Why do JWTs use Base64 URL?

JWTs travel in URLs, headers, and cookies — places where + and / have other meanings. The standards (RFC 7515 / 7519) mandate Base64 URL, no padding, throughout the format.

Can I just URL-encode standard Base64?

You can, but you'll pay 4 bytes per /, double-decode on the receiver, and run into double-encoding bugs when something else URL-encodes the result again. Base64 URL is the simpler answer and it's what other systems expect.

What about the padding?

Standard Base64 pads to a multiple of 4 with =. Base64 URL almost always strips them. To re-add: pad with = until the length is a multiple of 4. Some libraries fail without padding; the converter below re-pads automatically before decoding.

Is Base64 URL the same as 'web-safe Base64'?

Yes — different name for the same thing. RFC 4648 §5 defines it formally as 'base64url'. 'URL-safe Base64' and 'web-safe Base64' are common informal names.

Open the encoder →