What is a Blob and how does it differ from a File?
The Short Answer
A Blob (Binary Large Object) is an immutable chunk of raw binary data. It represents file-like data that doesn't necessarily come from the file system — it could be text you generated, an image you fetched, or bytes you constructed in memory. A File is just a Blob with a name and a last-modified timestamp bolted on.
What a Blob Looks Like
A Blob has only two properties — size (in bytes) and type (MIME type). It's intentionally simple. You can't modify a Blob once it's created — you can only read it or slice it into smaller Blobs.
// Create a Blob from a string
const textBlob = new Blob(['Hello, World!'], { type: 'text/plain' });
console.log(textBlob.size); // 13
console.log(textBlob.type); // "text/plain"
// Create a Blob from JSON
const data = { name: 'Alice', age: 30 };
const jsonBlob = new Blob([JSON.stringify(data)], { type: 'application/json' });
// Create a Blob from multiple parts (they get concatenated)
const multiBlob = new Blob(
['Part 1, ', 'Part 2, ', new Uint8Array([80, 97, 114, 116, 32, 51])],
{ type: 'text/plain' }
);
// Result: "Part 1, Part 2, Part 3"
// Create a Blob from another Blob + extra data
const combined = new Blob([textBlob, '\nMore text'], { type: 'text/plain' });
The constructor takes an array
The first argument to new Blob() is always an array of parts. Each part can be a string, an ArrayBuffer, a TypedArray, or another Blob. They get concatenated in order into one binary chunk.
Blob vs File
File extends Blob. It adds name and lastModified — that's it. Every File IS a Blob, but not every Blob is a File.
// A Blob — raw data, no filename
const blob = new Blob(['csv,data,here'], { type: 'text/csv' });
console.log(blob.name); // undefined
console.log(blob.lastModified); // undefined
// A File — a Blob with metadata
const file = new File(['csv,data,here'], 'export.csv', {
type: 'text/csv',
lastModified: Date.now()
});
console.log(file.name); // "export.csv"
console.log(file.lastModified); // 1717500000000
console.log(file.size); // 13 (inherited from Blob)
console.log(file instanceof Blob); // true ✓
// When a user picks a file via <input type="file">, you get a File object
const input = document.querySelector('input[type=file]') as HTMLInputElement;
input.addEventListener('change', () => {
const userFile = input.files![0]; // This is a File (which is a Blob)
console.log(userFile.name); // "photo.jpg"
console.log(userFile.size); // 2048000
console.log(userFile.type); // "image/jpeg"
});
When to use which
- ✅Use `Blob` when you're generating data in code (CSV export, JSON download, canvas image)
- ✅Use `File` when you need a filename (uploading to a server, drag-and-drop interfaces)
- ✅You receive `File` objects from `<input type="file">` and the Drag and Drop API
Reading a Blob's Contents
Blobs are opaque — you can't peek inside without explicitly reading them. There are two approaches: the modern async methods on Blob itself, and the older FileReader API.
const blob = new Blob(['Hello, Blob!'], { type: 'text/plain' });
// ✅ Modern approach (returns Promises — clean and simple)
const text = await blob.text(); // "Hello, Blob!"
const buffer = await blob.arrayBuffer(); // ArrayBuffer of raw bytes
const stream = blob.stream(); // ReadableStream for chunked reading
// 🕰️ Legacy approach (event-based — more verbose)
const reader = new FileReader();
reader.onload = () => console.log(reader.result); // "Hello, Blob!"
reader.readAsText(blob);
// FileReader also supports:
// reader.readAsArrayBuffer(blob) → ArrayBuffer
// reader.readAsDataURL(blob) → "data:text/plain;base64,SGVsbG8s..."
Prefer the modern methods
Use blob.text(), blob.arrayBuffer(), and blob.stream() in modern code. They return Promises, work with async/await, and are much cleaner than FileReader's callback-based API. Only fall back to FileReader if you need readAsDataURL() or must support very old browsers.
Slicing a Blob
blob.slice() creates a new Blob that references a portion of the original data — without copying it in memory. This is key for chunked uploads and large file processing.
const bigBlob = new Blob(['ABCDEFGHIJ']); // 10 bytes
// slice(start, end) — just like Array.slice()
const chunk1 = bigBlob.slice(0, 5); // "ABCDE"
const chunk2 = bigBlob.slice(5, 10); // "FGHIJ"
// Negative indices work too
const lastThree = bigBlob.slice(-3); // "HIJ"
// The original Blob is untouched — slicing creates a lightweight view
console.log(bigBlob.size); // still 10
console.log(chunk1.size); // 5
Practical Examples
// Generate and download a CSV file entirely in the browser
function downloadCSV(rows: string[][]) {
const csvContent = rows.map(row => row.join(',')).join('\n');
const blob = new Blob([csvContent], { type: 'text/csv' });
const url = URL.createObjectURL(blob); // Create a temporary URL
const a = document.createElement('a');
a.href = url;
a.download = 'export.csv';
a.click();
URL.revokeObjectURL(url); // Free memory
}
downloadCSV([['Name', 'Age'], ['Alice', '30'], ['Bob', '25']]);
// Preview an image before uploading it
const input = document.querySelector('input[type=file]') as HTMLInputElement;
const preview = document.querySelector('img') as HTMLImageElement;
input.addEventListener('change', () => {
const file = input.files![0]; // File is a Blob
if (!file.type.startsWith('image/')) return;
// Create a URL pointing to the Blob in memory
const objectURL = URL.createObjectURL(file);
preview.src = objectURL;
// Clean up when the image loads
preview.onload = () => URL.revokeObjectURL(objectURL);
});
// Convert a canvas drawing to a Blob and upload it
const canvas = document.querySelector('canvas') as HTMLCanvasElement;
canvas.toBlob(async (blob) => {
if (!blob) return;
const formData = new FormData();
formData.append('avatar', blob, 'avatar.png');
await fetch('/api/upload-avatar', {
method: 'POST',
body: formData
});
}, 'image/png');
Common Mistakes
Forgetting to revoke object URLs
Every `URL.createObjectURL()` keeps the Blob in memory until the page unloads or you explicitly revoke it. Creating many without revoking leaks memory.
✅Always call `URL.revokeObjectURL(url)` when you're done — after download completes or image loads.
Treating Blobs as mutable
Blobs are immutable. You can't modify their contents after creation. Trying to "edit" a Blob means creating a new one.
✅Read the Blob, modify the data, then create a new Blob from the modified data.
Why Interviewers Ask This
File handling is everywhere — uploads, downloads, image previews, PDF generation, clipboard operations. Understanding Blobs shows you can work with binary data in the browser, manage memory correctly, and build features like file exports without needing a server round-trip.
Quick Revision Cheat Sheet
Blob: Immutable binary data with `size` and `type` properties
File: A Blob subclass that adds `name` and `lastModified`
Reading: `blob.text()`, `blob.arrayBuffer()`, `blob.stream()`
Slicing: `blob.slice(start, end)` — lightweight, no copy
Object URL: `URL.createObjectURL(blob)` → temporary URL to the Blob in memory
Cleanup: Always `URL.revokeObjectURL()` when done to free memory