JavaScript Blob
Learn how to use JavaScript Blob objects to handle raw binary data: create and slice Blobs, generate and revoke Blob URLs, read content, and convert to Base64.
A Blob (short for Binary Large Object) represents immutable, raw, file-like data. It is the standard way to pass around chunks of binary content in the browser — text, images, audio, PDFs, anything — without forcing it into a JavaScript-native type such as a string or Array. A Blob is opaque: it holds bytes plus a MIME type, and you read those bytes asynchronously when you need them.
Blobs sit at the center of file handling on the web. A File is actually a specialized Blob with a name and a modification date, fetch() can hand you a response body as a Blob, and the canvas, the clipboard, and the download mechanism all speak Blob. This guide covers how to create, slice, link, read, and convert Blobs, plus the gotchas that trip people up.
What a Blob actually is
A Blob exposes two read-only properties and a few asynchronous reader methods:
blob.size— the length of the data in bytes.blob.type— the MIME type string (empty""if none was provided).blob.slice(start, end, type)— returns a new Blob for a byte range, without copying the underlying data.blob.text(),blob.arrayBuffer(),blob.bytes(),blob.stream()— promise-based (or stream-based) readers.
Because a Blob is immutable, none of these methods change the original — they always return a new Blob or a fresh read of the bytes.
Creating Blob objects
You create a Blob with its constructor, which takes two arguments: an array of parts and an optional options object.
new Blob(parts, options);Each item in parts can be a string, an ArrayBuffer, a TypedArray/DataView, or another Blob — they are concatenated in order. The options.type string is the MIME type, which tells consumers how to interpret the bytes (for example "text/plain", "image/jpeg", "application/json", or "audio/mpeg"). See MIME types for the full picture.
Combining and slicing Blobs
Because Blobs are immutable, you "edit" them by building a new Blob from existing parts. You can mix strings and Blobs freely in the parts array:
To go the other way and pull out a byte range, use blob.slice(start, end). It mirrors Array.prototype.slice: end is exclusive, and negative indices count from the end.
Working with Blob URLs
A Blob URL (also called an object URL) is a short-lived blob: URL that points at a Blob held in memory. You can drop it into any place that expects a URL — an <img src>, an <a href> download link, an <audio> element — so the browser can read the Blob as if it were a remote resource.
Generating Blob URLs
URL.createObjectURL(blob) returns a unique URL each time it is called:
Revoking Blob URLs
Each object URL keeps its Blob alive in memory until the document is unloaded — even after the element using it is gone. To avoid leaks, call URL.revokeObjectURL(url) once you are done with it:
const data = new Blob(["Example text"], { type: "text/plain" });
const blobUrl = URL.createObjectURL(data);
// ...use blobUrl, e.g. as an <a href> or <img src> ...
URL.revokeObjectURL(blobUrl); // frees the memory held by the Blob URLTriggering a file download
A common real-world use is letting the user download data your script generated, with no server round-trip. Create a Blob, wrap it in an object URL, click a temporary link, then revoke:
function downloadText(filename, text) {
const blob = new Blob([text], { type: "text/plain" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = filename; // suggested file name
a.click();
URL.revokeObjectURL(url); // clean up immediately after the click
}
downloadText("notes.txt", "Saved from the browser!");Reading Blob content
The modern, promise-based readers are the simplest way to get bytes out of a Blob:
The older FileReader API does the same job with events instead of promises. It is still useful when you need progress events or have to support legacy code:
For very large Blobs you can stream the bytes with blob.stream() instead of loading everything into memory at once, and blob.arrayBuffer() gives you a raw ArrayBuffer when you need low-level access to the binary data.
Converting a Blob to Base64
Base64 lets you embed binary data in text-only contexts such as JSON payloads or data URLs. FileReader.readAsDataURL() produces a data: URL whose payload is Base64-encoded:
Common gotchas
- Blobs are immutable. There is no method to append to or rewrite a Blob — build a new one from the parts you want.
- Reading is always asynchronous.
text(),arrayBuffer(), andFileReaderreturn their results later, so useawaitor.then(); the bytes are never available synchronously. sizecounts bytes, not characters. Multi-byte UTF-8 characters add up:new Blob(["é"]).sizeis2, not1.- Revoke your object URLs. A forgotten
createObjectURLkeeps its Blob in memory for the life of the page. typeis just a label. Settingtype: "image/png"does not validate that the bytes are a PNG; it only advertises the intended MIME type.
Where Blobs are used
- File uploads. Send a Blob (or a
File) as the body of afetch()request, optionally insideFormData. - Generated downloads. Build CSV, JSON, or text on the fly and hand it to the user via an object URL, as shown above.
- Canvas and image work.
canvas.toBlob(callback, type)turns a<canvas>into an image Blob you can upload or download. - Streaming large data. Slice and stream big binary payloads without loading everything into memory at once.
Conclusion
A Blob is the browser's container for immutable raw binary data: create one from strings or buffers, slice it without copying, link it through an object URL, and read it back with text(), arrayBuffer(), or FileReader. Remember that Blobs are immutable, reads are asynchronous, and object URLs must be revoked. With those rules in mind you can move files, generate downloads, and process media entirely on the client.
To go deeper, explore the related File and FileReader API and ArrayBuffer and typed arrays.