JavaScript Blob Table

PieceWhat it doesField note
new Blob(parts, {type})Build one from strings/Blobs/buffersParts concatenate in order; the type option sets the MIME downloads will carry
blob.sizeSize in BYTESNever compare to string.length - UTF-8 bytes vs UTF-16 units (an emoji: size 3-4, length 1)
blob.typeThe MIME stringWhat you passed in - empty string if built without a type; the download content-type comes from here
blob.slice(start, end)Cut WITHOUT copyingReturns a view over the same bytes - chunked uploads and range reads are just sequential slices
await blob.text()Read as stringThe modern read (replaces FileReader.readAsText); async, UTF-8 decoded
await blob.arrayBuffer()Read as raw bufferThe workspace for typed-array processing; convert back with new Blob([buffer])
await blob.stream()Read piecewiseReadableStream - process huge files without holding the whole thing in memory
URL.createObjectURL / revokeObjectURLThe download/display bridgeAn url string pointing at the blob in memory - revoke after use or it leaks per click in SPAs
Reference: the MDN Blob reference. A Blob is the browser's immutable container for raw bytes plus a MIME type - not a string, not a Buffer; text(), arrayBuffer() and stream() are READS you perform on it. Immutability is what makes slice() safe and cheap: cutting a chunk returns a view over the same bytes, which is exactly how chunked uploads and range requests work without duplicating data.
Bottom line: a File IS a Blob - File extends Blob with name and lastModified, so every Blob method works identically on uploaded files, and functions typed to accept Blobs are the reusable signature. The byte trap to internalize: size counts UTF-8 bytes, string length counts UTF-16 units - any upload limit, chunk size or Content-Length math must read blob.size, and conflating the two is the classic 'small' upload the server rejects.
Related tools: the File API table (reading user uploads into Blobs), the File System Access table (writing Blobs back to real files via handles), the fetch table (response.blob() and blob bodies on the way up), the typed arrays table (the ArrayBuffer workspace between reads and builds), and the compression streams table (gzip a Blob in the browser).

A Blob (Binary Large Object) is the browser's immutable container for raw bytes: file contents, generated exports, drawn canvas frames, fetched responses. It is NOT a string and NOT a Buffer - it carries bytes plus a MIME type, and everything else (text, array buffer, stream, object URL) is a read you perform on it.

Bottom line: Blobs are immutable and slice() is free - subBlob = blob.slice(start, end) returns a view without copying the data, which is how chunked uploads and range reads work. To let the user download or display one, wrap it in an object URL (URL.createObjectURL) and REVOKE it after use - skipped revocation is the classic memory leak of export-heavy pages.

The honest part: a File IS a Blob - File extends Blob with a name and last-modified date, so every File you get from an input works with every Blob method unchanged. And blob.size is BYTES while string.length is UTF-16 code units: a 3-byte emoji is size 3 (or 4 in UTF-8) but length 1, and conflating them corrupts byte math.

How to use

  1. Read a Blob as text: await blob.text() - the modern one-liner for file contents (replaces FileReader.readAsText for everything except progress UI).
  2. Read bytes: await blob.arrayBuffer() when you need typed-array access, or await blob.stream() for piecewise processing of large files without holding it all in memory.
  3. Trigger a download: const url = URL.createObjectURL(blob); a.href = url; a.download = 'export.csv'; a.click(); URL.revokeObjectURL(url); - revoke in the same tick family, not 'eventually'.
  4. Cut without copying: blob.slice(0, 1024 * 1024) gives a 1MB chunk view - chunked uploads send slices sequentially with per-chunk retry, and the source blob stays untouched.
  5. Build one from parts: new Blob([headerRow, dataBlob, footerRow], { type: 'text/csv' }) - strings and Blobs concatenate in order, and the type option sets the MIME the download will carry.

Frequently asked questions

What is the difference between a Blob and a File?

File is a Blob subclass with metadata: name and lastModified. Every Blob method - slice, text, arrayBuffer, stream, object URLs - works identically on both, which is why code written for generated Blobs handles uploaded files with zero changes. The direction to remember: you can construct a File from parts (new File([blob], 'name.png')) but you cannot strip a File back down to a nameless Blob - and functions typed to accept Blobs are the more reusable signature.

Why is my blob.size different from the string length I put in?

Encoding. A Blob stores UTF-8 BYTES; JavaScript strings are UTF-16 code units. The emoji is one code unit (length 1) but three or four UTF-8 bytes (size 3-4); non-Latin scripts diverge similarly. Any byte math - upload limits, chunk sizes, Content-Length headers - must read blob.size, never string length, and the mismatch is the root cause of servers rejecting 'small' uploads that are byte-heavy.

Do I really need revokeObjectURL if the page navigates away soon?

Yes on principle, no in effect for one-shot pages - the URL holds the blob in memory until the DOCUMENT unloads, so a download-and-navigate flow self-cleans. But single-page apps keep the document alive for the session: an export button clicked fifty times without revocation holds fifty blobs until refresh. Revoke right after the click handler (the download has already captured what it needs) and the leak never accumulates.

How is a Blob different from an ArrayBuffer?

A Blob is an opaque FILE-LIKE container (bytes + MIME, storable, downloadable, sliceable); an ArrayBuffer is a raw MEMORY buffer you view and edit through typed arrays. They convert in both directions - blob.arrayBuffer() to process, new Blob([buffer], {type}) to export - and the flow is: fetch or build bytes as ArrayBuffer, manipulate via typed arrays, wrap as Blob to save or display. Neither one is 'better'; they are storage format versus workspace.

Related tools