Base64 encode/decode · Guide
Base64 Decode and Download: Turn a Payload Back Into a File
APIs frequently return a document as a Base64 string rather than a binary body. Turning that back into a file the user can save is a small piece of code with several details that go wrong quietly.
In the browser
Decode to bytes, wrap them in a Blob with the correct MIME type, and hand the browser an object URL:
function downloadBase64(b64, filename, mime) {
const bytes = Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));
const url = URL.createObjectURL(new Blob([bytes], { type: mime }));
const a = document.createElement('a');
a.href = url;
a.download = filename;
a.click();
URL.revokeObjectURL(url); // release the memory
}revokeObjectURL is the line people forget: without it every download leaks memory until the tab closes, which matters in a long-lived single-page app.
Why not a data URI
Setting href to a data: URI works for small payloads and fails for large ones — browsers cap data URI length, and the whole string sits in the DOM. Blob URLs have no such limit and are the correct tool.
The MIME type matters for how the file opens: application/pdf previews in the browser, application/octet-stream always downloads. Choose according to the behaviour you want.
On the command line
For large payloads or a one-off, skip the browser entirely:
base64 -d payload.b64 > document.pdf
# from a JSON response
jq -r '.file' response.json | base64 -d > document.pdfIf decoding fails, look for base64url: translate - and _ back to + and / first with tr.
Frequently asked questions
Why is my downloaded file corrupt?
Usually the payload was truncated, or it was decoded as text somewhere in the pipeline instead of as bytes.
Do I need the correct MIME type?
The bytes are correct either way, but the MIME type decides whether the browser previews or downloads the file.
Is there a size limit?
Blob URLs are limited by available memory. For very large files, stream from a server URL instead of embedding Base64.
Ready to try it?
Open the free browser-based Base64 encode/decode and apply what you just read — no sign-up, runs locally.
Open the Base64 encode/decode tool