The File API lets JavaScript inspect and read user-selected files entirely client-side, before any network request — powering instant previews and client-side validation that would otherwise require a costly server round-trip.
1Accessing File Metadata Instantly
The moment a user selects a file via <input type="file">, its .files property becomes a FileList — an array-like collection where each entry is a File object exposing metadata: .name, .size (in bytes), .type (MIME type), and .lastModified. This metadata is available synchronously and immediately, useful for instant client-side checks like file-size limits or accepted-type validation before any content reading or upload occurs.
2Reading Actual Content With FileReader
A File object's metadata doesn't include the actual file content. Reading it requires a separate FileReader instance and one of its asynchronous read methods — readAsDataURL() (encodes the content as a base64 data URL, ideal for instant image previews), readAsText() (for text-based files like CSV or JSON), or readAsArrayBuffer() (for binary processing).
Being asynchronous and event-based, the read result is only available inside the onload callback once reading completes, not immediately after calling the read method.
3The Same File Interface From Input And Drag-And-Drop
As covered in the previous Drag and Drop API lesson, dropping files from the operating system onto a page exposes them via event.dataTransfer.files — and critically, this yields the exact same FileList/File interface as <input type="file">.files.
This means a single, well-written file-processing function can accept files from either interaction method without any special-casing, since both ultimately deliver identical File objects with the same metadata properties and the same FileReader compatibility for content access.
4Step-by-Step Breakdown
Reading File Contents, Entirely Client-Side. Before a file is ever uploaded to a server, the File API lets JavaScript inspect its metadata and read its actual contents entirely client-side — powering instant image previews, client-side CSV parsing, and file-type validation before any network request happens.
input.files Yields A FileList Of File Objects. An <input type="file"> element's .files property is a FileList — an array-like collection of File objects, each carrying metadata (name, size, type, lastModified) about a user-selected file, accessible the instant selection happens.
Accessing Selected Files. What type of object does <input type="file">.files return?
- →A plain JavaScript Array
- →A FileList, an array-like collection of File objects
- →A single string representing the file's local path
FileReader Reads Actual File Contents Asynchronously. A File object alone only exposes metadata — reading actual content requires FileReader, an event-based, asynchronous API with methods like readAsDataURL() (for image previews) and readAsText() (for text/CSV files), completing via the onload event.
Reading File Content. Does a File object by itself give you access to the file's actual content, like image pixel data or text?
- →Yes, File objects directly expose their content synchronously
- →No, a separate FileReader instance is needed to asynchronously read the actual content
- →Only for image files specifically
File Objects Also Come From Drag-And-Drop. Recall the Drag and Drop API lesson: dropping OS files onto a page exposes them via event.dataTransfer.files, the exact same FileList/File interface as a file input — meaning both interaction methods feed into identical downstream processing code.
File Objects From Multiple Sources. When a user drags files from their desktop onto a drop zone, what interface exposes those files, connecting back to the Drag and Drop API lesson?
- →An entirely separate DragFile API unrelated to input.files
- →event.dataTransfer.files, the same File/FileList interface as a file input
- →Files must first be manually uploaded before becoming accessible
File API Mastered. You now know how to access selected file metadata via FileList/File, read actual file content asynchronously with FileReader, and that both file inputs and drag-and-drop deliver the exact same File interface, enabling unified handling code.
Add A File Picker. The File API starts with a native file input in the DOM.
Level Up 🚀
Advanced cheat sheets, SEO tricks, and interview prep for this topic.
Browser Support
Fully supported.
Fully supported.
Fully supported.
Fully supported.
Accessibility (A11y)
1A File Input Remains Fully Keyboard-Accessible By Default
Unlike native drag and drop, the underlying <input type="file"> file-selection dialog is fully keyboard and screen-reader operable, making it an essential accessible fallback alongside any drag-and-drop enhancement.
SEO Implications
- 1
Client-Side File Validation Reduces Unnecessary Server Load And Failed Upload Round-Trips
Catching invalid file types or oversized files before upload improves perceived performance and reduces wasted network requests, indirectly supporting a better overall user experience metric profile.
Best Practices
Validate File Size And Type Client-Side Before Attempting Upload, But Always Re-Validate Server-Side
Client-side checks improve UX by catching obvious problems instantly, but like all client-side validation covered in the Modern Forms module, must never be the sole line of defense.
Always Provide A Standard File Input Alongside Any Drag-And-Drop Enhancement
Since native drag and drop isn't keyboard-accessible, the file input serves as both a progressive-enhancement fallback and the accessible primary interaction path.
Frequent Bugs
Code tries to access file content immediately after calling reader.readAsDataURL(), getting undefined.
FileReader is asynchronous — access the result only inside the reader.onload callback, after reading actually completes.
A drag-and-drop file handler and a file-input handler duplicate significant processing logic.
Extract shared logic into one function accepting a FileList, called identically from both dataTransfer.files and input.files.
Real-World Examples
Instant Image Preview On Selection
A profile photo upload form showing an instant preview before the file is actually uploaded to the server.
fileInput.addEventListener('change', (e) => {
const file = e.target.files[0];
const reader = new FileReader();
reader.onload = (ev) => { preview.src = ev.target.result; };
reader.readAsDataURL(file);
});