How to Base64 Encode and Decode in JavaScript, Python and the Terminal
Copy-ready Base64 encode and decode examples for JavaScript, Node.js, Python, Linux, macOS and PowerShell, including Unicode text and the newline mistake.
The short answer
Every major language has Base64 built in: btoa() and atob() in browsers, Buffer in Node.js, the base64 module in Python, the base64 command on Linux and macOS, and [Convert]::ToBase64String in PowerShell. The one trap is text encoding: convert text to UTF-8 bytes first, or non-English characters will fail or decode wrongly. To check any result by hand, paste it into the free Base64 Encoder/Decoder, which encodes text as UTF-8 and decodes back to readable text.
All examples below use the text Hello, World!, which encodes to SGVsbG8sIFdvcmxkIQ==. The outputs shown were produced by running the code.
JavaScript in the browser
- Encode:
btoa('Hello, World!')returnsSGVsbG8sIFdvcmxkIQ== - Decode:
atob('SGVsbG8sIFdvcmxkIQ==')returnsHello, World!
btoa only accepts characters in the Latin-1 range. Hindi, emoji or Chinese text throws an InvalidCharacterError. Encode to UTF-8 bytes first:
const bytes = new TextEncoder().encode('नमस्ते')const b64 = btoa(String.fromCharCode(...bytes)) gives 4KSo4KSu4KS44KWN4KSk4KWHnew TextDecoder().decode(Uint8Array.from(atob(b64), c => c.charCodeAt(0))) gives नमस्तेThe spread into String.fromCharCode is fine for normal strings. For very large data, process it in chunks to avoid hitting the argument limit.
Node.js
Node has Buffer, which handles UTF-8 for you:
- Encode:
Buffer.from('Hello, World!', 'utf8').toString('base64')returnsSGVsbG8sIFdvcmxkIQ== - Decode:
Buffer.from('SGVsbG8sIFdvcmxkIQ==', 'base64').toString('utf8')returnsHello, World!
To encode a file, read it as a buffer: fs.readFileSync('logo.png').toString('base64').
Python
Python's base64 functions work on bytes, so encode and decode the text explicitly:
- First:
import base64 - Encode:
base64.b64encode('Hello, World!'.encode('utf-8')).decode('ascii')returnsSGVsbG8sIFdvcmxkIQ== - Decode:
base64.b64decode('SGVsbG8sIFdvcmxkIQ==').decode('utf-8')returnsHello, World!
For URL-safe Base64 (used in JWTs and some APIs), use urlsafe_b64encode. It swaps + for - and / for _. For the bytes FB FF, standard Base64 gives +/8= and URL-safe gives -_8=.
Linux terminal
- Encode:
printf 'Hello, World!' | base64printsSGVsbG8sIFdvcmxkIQ== - Decode:
echo 'SGVsbG8sIFdvcmxkIQ==' | base64 -dprintsHello, World!
To encode a file on one line, use base64 -w 0 file.png. Without -w 0, GNU base64 wraps long output every 76 characters, which breaks data URIs and JSON fields.
The newline mistake
echo 'Hello, World!' | base64 gives SGVsbG8sIFdvcmxkIQo=, not SGVsbG8sIFdvcmxkIQ==. The difference is because echo adds a line break at the end, and the line break is encoded too. Use printf or echo -n when you want to encode exactly the text you typed. This one detail explains a large share of "my Base64 doesn't match" questions.
macOS terminal
macOS also has a base64 command, but its options differ from the Linux version and have changed between macOS releases. printf 'Hello, World!' | base64 works the same way. For files and decoding, check man base64 on your Mac for the exact input, output and decode flags, rather than copying Linux flags such as -w.
Windows PowerShell
PowerShell uses .NET methods. Choose the text encoding explicitly:
- Encode:
[Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes('Hello, World!'))returnsSGVsbG8sIFdvcmxkIQ== - Decode:
[Text.Encoding]::UTF8.GetString([Convert]::FromBase64String('SGVsbG8sIFdvcmxkIQ=='))returnsHello, World!
Some Windows tools and APIs expect UTF-16 text ([Text.Encoding]::Unicode) instead of UTF-8. The two give different Base64 for the same words, so use whichever the receiving system expects.
Encoding files instead of text
The same functions work on any bytes, not just text, which is how images, PDFs and certificates end up inside JSON, emails and HTML:
- Node.js:
fs.readFileSync('photo.jpg').toString('base64')returns the whole file as one Base64 string. - Python: open the file in binary mode and pass the bytes in:
base64.b64encode(open('photo.jpg', 'rb').read()).decode('ascii'). - Linux:
base64 -w 0 photo.jpgprints it on a single line; redirect it withbase64 -w 0 photo.jpg > photo.txtto save it. - PowerShell:
[Convert]::ToBase64String([IO.File]::ReadAllBytes('photo.jpg')).
Expect the output to be about a third larger than the file, because every 3 bytes become 4 characters. A 300 KB image becomes roughly 400 KB of text. That overhead is why Base64 suits small icons and attachments but not large photos.
To use an encoded image in HTML or CSS, add the data URI prefix that names the file type, for example data:image/png;base64, followed by the encoded string. A wrong type in the prefix is one of the most common reasons an embedded image does not show. The image to Base64 converter adds the correct prefix for you.
Quick reference
| Environment | Encode | Decode |
|---|---|---|
| Browser JS | btoa(str) (Latin-1 only) | atob(b64) |
| Node.js | Buffer.from(s).toString('base64') | Buffer.from(b64, 'base64').toString() |
| Python | base64.b64encode(b) | base64.b64decode(s) |
| Linux | base64 | base64 -d |
| PowerShell | [Convert]::ToBase64String(bytes) | [Convert]::FromBase64String(s) |
Checking your output with the online tool
When a script gives an unexpected result, compare it with a known-good encoder:
The tool converts text through UTF-8, so नमस्ते encodes to 4KSo4KSu4KS44KWN4KSk4KWH, the same as the Python and Node examples above. It works on text only; to turn an image into Base64, use the image to Base64 converter.
Common errors and fixes
InvalidCharacterErrorfrom btoa: the text contains characters outside Latin-1. Use the TextEncoder method.- Padding errors when decoding: the string length must be a multiple of 4; missing
=signs at the end cause errors in strict decoders. See fixing Base64 decode errors. - Garbled accented letters after decoding: the text was encoded as UTF-8 but decoded as Latin-1, or the reverse. Use the same encoding on both sides.
+and/breaking a URL: use URL-safe Base64, or URL-encode the result.
Remember that Base64 is an encoding, not encryption. Anyone can decode it. For why it exists and how the 3-bytes-to-4-characters rule works, read Base64 encoding explained.
Frequently asked questions
How do I Base64 encode a string in JavaScript?
In a browser use btoa(text) for plain English text. For Unicode text, convert to UTF-8 bytes with TextEncoder first. In Node.js use Buffer.from(text, "utf8").toString("base64").
Why does echo | base64 give a different result?
echo adds a line break to the end of the text, and base64 encodes that line break too. Use printf or echo -n to encode only the characters you typed.
How do I decode Base64 in Python?
Use base64.b64decode(s) to get bytes, then .decode("utf-8") to turn the bytes into text, for example base64.b64decode("SGVsbG8sIFdvcmxkIQ==").decode("utf-8") returns "Hello, World!".
Why does btoa throw InvalidCharacterError?
btoa only accepts characters in the Latin-1 range. Text with Hindi, emoji or other non-Latin characters must be converted to UTF-8 bytes before encoding.
Put this guide into practice with our free online tool — no signup required.
Open tool