How to Base64 Encode and Decode in Python, JavaScript, and Java
Table of Contents
Base64 encoding and decoding is a standard operation in almost every programming language, but the exact function names and import paths differ enough to trip you up when switching between them. This guide collects the most common patterns in Python, JavaScript (browser and Node.js), and Java — all in one place.
If you need to quickly decode or encode a specific string without writing code, the free Base64 tool linked below handles it instantly in your browser with no setup required.
Base64 in Python — b64encode and b64decode
Python's standard library includes the base64 module. No installation needed.
import base64
# Encode
text = "Hello, World!"
encoded = base64.b64encode(text.encode('utf-8'))
print(encoded) # b'SGVsbG8sIFdvcmxkIQ=='
print(encoded.decode()) # SGVsbG8sIFdvcmxkIQ== (as string)
# Decode
encoded_str = "SGVsbG8sIFdvcmxkIQ=="
decoded = base64.b64decode(encoded_str)
print(decoded.decode('utf-8')) # Hello, World!
Key points: b64encode() takes bytes, not a string — use .encode('utf-8') first. It returns bytes — use .decode() to get a string. For URL-safe Base64 (replacing + with - and / with _), use base64.urlsafe_b64encode() and base64.urlsafe_b64decode().
Base64 in JavaScript — Browser Built-ins
Modern browsers have two built-in global functions for Base64:
// Encode
const text = "Hello, World!";
const encoded = btoa(text);
console.log(encoded); // SGVsbG8sIFdvcmxkIQ==
// Decode
const decoded = atob("SGVsbG8sIFdvcmxkIQ==");
console.log(decoded); // Hello, World!
Unicode gotcha: btoa() only handles Latin-1 characters. If your string contains characters outside that range (emoji, Chinese characters, accented letters), you will get a DOMException: The string contains an invalid character error. The fix:
// Unicode-safe encode const encoded = btoa(unescape(encodeURIComponent(text))); // Unicode-safe decode const decoded = decodeURIComponent(escape(atob(encodedStr)));
These two patterns handle any Unicode input correctly and are what our online encoder uses under the hood.
Base64 in Node.js — Buffer API
Node.js uses the Buffer class for Base64, which handles Unicode correctly without workarounds:
// Encode
const text = "Hello, World!";
const encoded = Buffer.from(text, 'utf-8').toString('base64');
console.log(encoded); // SGVsbG8sIFdvcmxkIQ==
// Decode
const decoded = Buffer.from("SGVsbG8sIFdvcmxkIQ==", 'base64').toString('utf-8');
console.log(decoded); // Hello, World!
// URL-safe Base64 (no + or / characters)
const urlSafe = Buffer.from(text, 'utf-8').toString('base64url');
The Node.js Buffer API is the preferred approach for server-side JavaScript. Unlike browser btoa(), it handles multi-byte Unicode correctly without extra encoding steps. The base64url encoding option (available since Node.js 14.18) produces URL-safe output automatically.
Base64 in Java — java.util.Base64
Java 8 introduced java.util.Base64, which replaced the older (non-standard) sun.misc.BASE64Encoder. Always use the standard library:
import java.util.Base64;
import java.nio.charset.StandardCharsets;
// Encode
String text = "Hello, World!";
String encoded = Base64.getEncoder().encodeToString(
text.getBytes(StandardCharsets.UTF_8)
);
System.out.println(encoded); // SGVsbG8sIFdvcmxkIQ==
// Decode
byte[] decodedBytes = Base64.getDecoder().decode(encoded);
String decoded = new String(decodedBytes, StandardCharsets.UTF_8);
System.out.println(decoded); // Hello, World!
// URL-safe variant (no + or /)
String urlSafe = Base64.getUrlEncoder().encodeToString(
text.getBytes(StandardCharsets.UTF_8)
);
Java provides three encoder variants: getEncoder() for standard Base64, getUrlEncoder() for URL-safe Base64, and getMimeEncoder() for MIME-formatted output with line breaks (used in email attachments and PEM certificate files).
Quick Comparison — Base64 Across Languages
| Language | Encode | Decode | Unicode Safe? |
|---|---|---|---|
| Python | base64.b64encode() | base64.b64decode() | Yes (with .encode('utf-8')) |
| JS (Browser) | btoa() | atob() | No — needs workaround |
| Node.js | Buffer.from().toString('base64') | Buffer.from(str,'base64').toString() | Yes |
| Java | Base64.getEncoder().encodeToString() | Base64.getDecoder().decode() | Yes (with UTF-8 bytes) |
When working across languages, always encode with a specified character encoding (UTF-8 is the safest default) and specify the same encoding when decoding. Mismatched encodings are the most common cause of garbled output when Base64 data crosses language boundaries.
Testing Your Encoding Online — Verify Without Running Code
When debugging Base64 issues in code, it helps to have a reference point. If you are unsure whether your encoded output is correct, paste the string into the free encoder/decoder tool below. It will immediately decode it back to text so you can verify the result matches what you intended to encode.
This is particularly useful when tracing API responses that contain Base64-encoded fields — JWT payloads, Kubernetes secrets, configuration values — where you want to inspect the content without writing a decode script. Paste the string, click Decode, and see the contents in seconds.
Try It Free — No Signup Required
Runs 100% in your browser. No data is collected, stored, or sent anywhere.
Open Free Base64 Encoder/DecoderFrequently Asked Questions
Why does btoa() throw an error on some strings?
btoa() only handles characters in the Latin-1 range (code points 0-255). Multi-byte Unicode characters (emoji, Chinese, Arabic, etc.) outside that range cause a DOMException. Use btoa(unescape(encodeURIComponent(str))) for Unicode-safe encoding.
Is the Base64 output the same across all languages?
Yes — standard Base64 produces identical output regardless of the language used, as long as the input bytes are the same. If you encode "Hello" in Python and JavaScript you get the same result. Differences only appear when using URL-safe variants or MIME variants.
What is the difference between base64 and base64url?
Standard Base64 uses + and / as the 62nd and 63rd characters. These characters have special meaning in URLs, so base64url replaces + with - and / with _. JWT tokens use base64url encoding for this reason.

