Base64 encoder / decoder
- Runs on your device
- Nothing uploaded
- Free, no sign-up
Client-side only. Text is UTF-8 encoded before Base64. Nothing is uploaded.
Same string, two alphabets
Base64 turns bytes into ASCII. The classic alphabet uses + and /. URL-safe (RFC 4648 base64url) swaps those for - and _ so the value survives query strings. Same input bytes, different characters:
| Input (UTF-8) | Standard | URL-safe (no pad) |
|---|---|---|
Hi? | SGk/ | SGk_ |
a+b | YSti | YSti (no +/ here) |
subjects?_d | contains +// when those bytes appear | uses -/_ instead |
Hello, ToolPetal | SGVsbG8sIFRvb2xQZXRhbA== | SGVsbG8sIFRvb2xQZXRhbA |
Tick URL-safe when the consumer expects base64url (JWTs, many OAuth challenges). Leave it off for classic MIME-style Base64.
Encode path, decode traps
Encode: this page runs TextEncoder (UTF-8), then Base64. Emoji and accented characters are fine; legacy Latin-1-only encoders are not what you get here.
Decode: Base64 first, then TextDecoder with fatal: true. If the bytes are not valid UTF-8 text, you get an error instead of silent garbage. Binary blobs belong in a hex or file tool, not in a text box pretending to be UTF-8.
Padding (=): some APIs strip it. Leave Keep / restore = padding on unless you know the peer wants unpadded strings. On decode, missing padding is restored when the length needs it.
What this page will not do
- Upload or store your payload (there is no server round-trip).
- Decode huge binary files pasted as Base64; keep inputs modest for a textarea.
- Guess between standard and URL-safe for you. Pick the alphabet your API documents.
- Replace a JWT debugger: for HS256 minting see the JWT encoder; for OAuth S256 see the PKCE generator.
Base64 and Base64url in code
Encode UTF-8 text with the standard and URL-safe alphabets, then decode it back. The output matches this page.
JavaScript: Buffer (Node) and btoa (browser)
// Node.js: Buffer handles UTF-8 and the URL-safe alphabet
const std = Buffer.from("héllo ✓", "utf8").toString("base64");
const url = Buffer.from("héllo ✓", "utf8").toString("base64url"); // no padding
console.log(std, url, Buffer.from(std, "base64").toString("utf8"));
// Browser: btoa only takes Latin-1, so encode UTF-8 bytes first
const bytes = new TextEncoder().encode("héllo ✓");
const b64 = btoa(String.fromCharCode(...bytes));
const back = new TextDecoder().decode(Uint8Array.from(atob(b64), (c) => c.charCodeAt(0)));
console.log(b64, back);
Python: base64 module
import base64
raw = "héllo ✓".encode("utf-8")
std = base64.b64encode(raw).decode("ascii")
url = base64.urlsafe_b64encode(raw).rstrip(b"=").decode("ascii")
print(std, url)
# Decoding URL-safe input: put the padding back first
padded = url + "=" * (-len(url) % 4)
print(base64.urlsafe_b64decode(padded).decode("utf-8"))
Go: encoding/base64
package main
import (
"encoding/base64"
"fmt"
)
func main() {
raw := []byte("héllo ✓")
std := base64.StdEncoding.EncodeToString(raw)
url := base64.RawURLEncoding.EncodeToString(raw) // URL-safe, no padding
fmt.Println(std, url)
back, err := base64.RawURLEncoding.DecodeString(url)
if err != nil {
panic(err)
}
fmt.Println(string(back))
}
Each snippet was run on October 14, 2026 with Node.js 20, Python 3.14 and Go 1.24.
Base64 specs: RFC 4648 and docs
- RFC 4648: The Base16, Base32, and Base64 Data Encodings
- RFC 4648, section 4: Base64: the + and / alphabet with = padding
- RFC 4648, section 5: Base64url: the - and _ alphabet used in JWTs and URLs
- MDN: btoa(): why it throws on characters outside Latin-1
- Node.js docs: Buffer encodings
- Python docs: base64
- Go docs: encoding/base64
FAQ
Does this Base64 tool upload my text?
No. Encoding and decoding run in JavaScript on this page. ToolPetal has no backend for Base64 conversion.
What is the difference between standard Base64 and URL-safe?
Standard Base64 uses + and / and often ends with = padding. URL-safe (base64url) swaps those for - and _ so the string survives query strings and path segments. Toggle URL-safe on this page when you need that alphabet.
Why does decode fail on some strings?
Common causes: wrong alphabet (standard vs URL-safe), missing or extra = padding, whitespace you meant to keep, or bytes that are not valid UTF-8 when decoded as text. This page reports the error instead of inventing output.
Is Unicode handled correctly?
Yes for text mode. Encode runs TextEncoder (UTF-8) before Base64. Decode runs TextDecoder (UTF-8, fatal) after Base64 so invalid byte sequences surface as errors rather than mojibake.