Glossary

Blob

Blob stands for Binary Large Object, an immutable browser object that holds a sequence of raw bytes together with a MIME type. It is defined by the W3C File API specification, and File inherits from it. You meet it when you build a download, upload a file, read a fetch response with blob(), or create a URL for in-memory data. A Blob is read-only: once created, its bytes never change.

How it works

The constructor takes an array of parts and an optional options object: new Blob(parts, { type, endings }). Each part can be a string, an ArrayBuffer, a typed array or another Blob. Strings are encoded as UTF-8, and the parts are joined in order.

Two read-only properties describe it. size is the byte count, not the character count. type is the media type as a lowercase string, or an empty string if unknown. If you pass a type containing characters outside printable ASCII, it becomes an empty string. The endings option accepts "transparent" (default) or "native" to convert line endings in string parts.

Reading a Blob is asynchronous. The promise methods are text(), arrayBuffer(), bytes() and stream(). The text() method always decodes as UTF-8. The older FileReader can pick another encoding.

slice(start, end, contentType) returns a new Blob covering bytes from start up to but not including end. Negative numbers count from the end, as with arrays. The new Blob has no connection to the original beyond its bytes, and its type is the third argument, or empty if omitted.

(async () => {
  const b = new Blob(['héllo ', new Uint8Array([119, 111, 114, 108, 100])], { type: 'Text/Plain' });
  console.log(b.size, b.type, b instanceof Blob);
  const s = b.slice(0, 6, 'text/x-part');
  console.log(s.size, s.type, await s.text());
  console.log(await b.slice(-5).text(), (await b.slice(1,3).bytes()));
  console.log(new Blob([]).size, new Blob(['x'], {type:'é'}).type === '');
  console.log(Object.prototype.toString.call(b), JSON.stringify({ b }));
})();

Output from Node 22.22.0:

12 text/plain true
6 text/x-part héllo
world Uint8Array(2) [ 195, 169 ]
0 true
[object Blob] {"b":{}}

The string "héllo " is 6 characters but 7 bytes, because é takes 2 bytes in UTF-8, which is why size is 12.

How do I turn a Blob into a downloadable file?

Call URL.createObjectURL(blob), which returns a string starting with blob:, put it in an anchor with a download attribute, click it, then call URL.revokeObjectURL(url). The object URL keeps the Blob alive in memory until you revoke it or the document unloads, so always revoke it.

Common pitfalls

  • Counting characters instead of bytes: blob.size for "héllo" is 6, not 5. Use size for byte limits and upload checks.
  • Forgetting to revoke object URLs: each createObjectURL call holds the data in memory until revokeObjectURL runs. Revoke after the download or image load finishes.
  • Expecting JSON.stringify to work: JSON.stringify({ b }) gives {"b":{}} because a Blob has no own enumerable properties, so the data is lost. Read it with text() or send it in FormData.
  • Assuming the type is trusted: the type is whatever the code or the file extension claims. Do not use it for security checks on uploads; validate bytes on the server.
  • Reading a huge Blob with text(): it loads everything into memory. Use stream() to process chunks.
  • Mutating after creation: you cannot edit a Blob. Build a new one from [old, extra] instead.

Related terms

  • File API — the specification that defines Blob, File and FileReader.
  • FileReader — the event-based reader for a Blob.
  • FormData — wraps a Blob as a file part for multipart uploads.
  • Fetch API — response.blob() returns a Blob, and a Blob can be a request body.
  • Structured clone — Blob objects survive postMessage and structuredClone.
  • Transferable object — contrast: a Blob is cloned, not transferred.

See also