JavaScript File Handling

Beginner
⏱️ 12 min read
📚 Updated: Jul 2026
🎯 5 Examples
🚀 5 Try-it labs
File API

What You’ll Learn

File handling lets web apps work with files the user chooses—text notes, images, CSV exports, and more. This tutorial covers the browser File API, FileReader, validation, security basics, and five hands-on examples you can run in the Try-it editor.

01

Pick files

<input type="file">

02

Read text

readAsText

03

Preview images

readAsDataURL

04

Validate

Size & MIME checks

05

Handle errors

onerror events

06

Stay safe

Blob URL cleanup

Introduction

JavaScript file handling is how you read and process files inside a web page or on a server. In the browser, users pick a file from their device; your script receives a File object and can inspect metadata or read the contents without reloading the page.

This guide focuses on client-side file handling with the File API and FileReader—the skills you need for previews, local parsing, and upload validation. We also touch on Node.js fs so you know where server-side reading and writing happens.

What Is File Handling in JavaScript?

File handling means working with file data programmatically: reading text, previewing images, checking size limits, or preparing a file for upload. In the browser, JavaScript never gets free access to the user’s hard drive—the user must choose each file through a trusted picker or drag-and-drop zone.

Once selected, a File extends Blob with a name and lastModified date. You read bytes with FileReader or modern promise helpers like file.text() and file.arrayBuffer().

💡
Beginner Tip

Think of File as a handle to the user’s document and FileReader as the tool that opens it and hands you the contents when ready.

Key Features

  • User-driven access — files come from explicit user action, not silent disk scans.
  • Asynchronous reads — large files load in the background so the page stays responsive.
  • Text and binary — read plain text, base64 data URLs, or raw ArrayBuffer bytes.
  • Form integration — pair with <input type="file"> and optional drag-and-drop.

Client-Side vs Server-Side

  • Browser (File API) — read files locally for preview or validation before upload.
  • Node.js (fs) — read and write files on the server filesystem; never expose raw server paths to the client.

Usage — File Input and FileReader

Start with an HTML file picker, then listen for the change event:

HTML
<input type="file" id="fileInput" accept=".txt,text/plain">

Capture the selected file in JavaScript:

JavaScript
const fileInput = document.getElementById("fileInput");

fileInput.addEventListener("change", (event) => {
  const file = event.target.files[0];
  if (!file) return;

  console.log("Name:", file.name);
  console.log("Size:", file.size, "bytes");
  console.log("Type:", file.type || "unknown");
});

Read the file contents with FileReader:

JavaScript
const reader = new FileReader();

reader.onload = (event) => {
  console.log("Content:", event.target.result);
};

reader.onerror = () => {
  console.error("Read failed:", reader.error);
};

reader.readAsText(file);

📝 Common FileReader Methods

JavaScript
reader.readAsText(file);        // string (UTF-8 text)
reader.readAsDataURL(file);     // base64 data URL (images)
reader.readAsArrayBuffer(file); // raw binary bytes

Modern promise helpers (File/Blob)

  • await file.text() — returns file contents as a string.
  • await file.arrayBuffer() — returns raw bytes for binary processing.
  • URL.createObjectURL(file) — creates a temporary URL for preview or download.

Important properties on File

  • file.name — filename including extension.
  • file.size — size in bytes.
  • file.type — MIME type (may be empty for some extensions).
  • file.lastModified — timestamp from the filesystem.

⚡ Quick Reference

GoalApproach
Let user pick a file<input type="file"> + change event
Read plain textreader.readAsText(file) or file.text()
Preview an imagereader.readAsDataURL(file)img.src
Read binary datareader.readAsArrayBuffer(file)
Limit file sizeif (file.size > maxBytes) …
Free memoryURL.revokeObjectURL(url)

📋 Reading Strategies

Pick the right tool for the job. Text viewers, image previews, and binary parsers each use a different read mode.

Text files
readAsText(file)

.txt, .csv, .json

Image preview
readAsDataURL(file)

Set img.src

Binary bytes
readAsArrayBuffer

PDF, audio, custom formats

Modern async
await file.text()

Promise-based alternative

Examples Gallery

Each example runs in the browser. Open DevTools (F12) for console output, or use the Try-it links for a live file picker in the editor.

📚 Getting Started

Select a file and inspect basic metadata.

Example 1 — Log File Name, Size, and Type

When the user picks a file, read its metadata from the File object—no FileReader needed yet.

JavaScript
const fileInput = document.getElementById("fileInput");

fileInput.addEventListener("change", (event) => {
  const file = event.target.files[0];
  if (!file) return;

  console.log("Selected:", file.name);
  console.log("Size (KB):", (file.size / 1024).toFixed(1));
  console.log("MIME type:", file.type || "(empty — check extension too)");
});
Try It Yourself

How It Works

event.target.files is a FileList. Index 0 is the first selected file. Metadata is available immediately; you only need FileReader when you want the actual bytes or text inside the file.

📈 Practical Patterns

Read contents, preview media, and validate before processing.

Example 2 — Read a Text File with FileReader

Display the contents of a plain-text file in a <pre> element.

JavaScript
const fileInput = document.getElementById("fileInput");
const output = document.getElementById("fileContent");

fileInput.addEventListener("change", (event) => {
  const file = event.target.files[0];
  if (!file) return;

  const reader = new FileReader();

  reader.onload = (e) => {
    output.textContent = e.target.result;
  };

  reader.readAsText(file);
});
Try It Yourself

How It Works

readAsText decodes the file as UTF-8 text. When the read finishes, onload fires and event.target.result holds the full string. For modern browsers you can also write output.textContent = await file.text() inside an async handler.

Example 3 — Preview an Image with readAsDataURL

Turn an image file into a data URL and assign it to an <img> element for instant preview.

JavaScript
const fileInput = document.getElementById("fileInput");
const preview = document.getElementById("preview");

fileInput.addEventListener("change", (event) => {
  const file = event.target.files[0];
  if (!file || !file.type.startsWith("image/")) {
    preview.removeAttribute("src");
    preview.alt = "Please choose an image file.";
    return;
  }

  const reader = new FileReader();
  reader.onload = (e) => {
    preview.src = e.target.result;
    preview.alt = "Preview of " + file.name;
  };
  reader.readAsDataURL(file);
});
Try It Yourself

How It Works

readAsDataURL produces a string like data:image/png;base64,… that browsers can load directly as an image source. Alternatively, preview.src = URL.createObjectURL(file) is faster for large files—just remember to revoke the URL when done.

Example 4 — Validate File Size and Type

Reject files that are too large or not plain text before spending time reading them.

JavaScript
const MAX_BYTES = 1024 * 1024; // 1 MB

function validateFile(file) {
  if (file.size > MAX_BYTES) {
    return "File is too large. Max size is 1 MB.";
  }
  if (!file.type.startsWith("text/") && !file.name.endsWith(".txt")) {
    return "Only plain text files are allowed.";
  }
  return null; // valid
}

fileInput.addEventListener("change", (event) => {
  const file = event.target.files[0];
  if (!file) return;

  const error = validateFile(file);
  if (error) {
    status.textContent = error;
    fileInput.value = "";
    return;
  }

  status.textContent = "Valid file: " + file.name;
});
Try It Yourself

How It Works

Client-side checks improve UX by giving instant feedback. They are not a security boundary—always validate again on the server before trusting uploaded content.

Example 5 — Text File Viewer with Error Handling

A complete mini viewer: pick a .txt file, show its contents, and surface read errors gracefully.

JavaScript
fileInput.addEventListener("change", (event) => {
  const file = event.target.files[0];
  const output = document.getElementById("fileContent");

  if (!file) {
    output.textContent = "No file selected.";
    return;
  }

  const reader = new FileReader();

  reader.onload = (e) => {
    output.textContent = e.target.result;
  };

  reader.onerror = () => {
    output.textContent = "Could not read file: " + reader.error;
  };

  reader.onabort = () => {
    output.textContent = "File read was cancelled.";
  };

  output.textContent = "Reading " + file.name + "…";
  reader.readAsText(file);
});
Try It Yourself

How It Works

Hooking onerror and onabort prevents silent failures. Showing a loading message before readAsText gives users feedback while large files decode.

🚀 Common Use Cases

  • Image upload preview — show a thumbnail before sending to the server.
  • CSV / JSON import — parse local data files without a round trip.
  • Resume or document picker — validate PDF size and type on the client.
  • Drag-and-drop zones — accept dataTransfer.files from drop events.
  • Client-side compression — read bytes with ArrayBuffer before upload.
  • Offline tools — notepad-style apps that never leave the browser until export.

Important Considerations

  • No silent disk access — users must pick files; never assume a path.
  • Client validation ≠ security — re-check type, size, and content on the server.
  • Large files — reading multi-megabyte files into memory can freeze weak devices; consider chunking or streaming on the server.
  • Empty MIME types — some OS files report file.type === ""; fall back to extension checks.
  • Memory leaks — revoke blob URLs with URL.revokeObjectURL when previews change.
  • Sensitive data — treat file contents as user data; avoid logging secrets to the console in production.

🧠 How Browser File Reading Works

1

User selects file

The browser opens a picker. JavaScript receives a File reference in the change handler.

Picker
2

Optional validation

Check size, type, and extension before reading bytes.

Guard
3

Start async read

Call readAsText, readAsDataURL, or file.text(). The main thread stays free.

Read
4

Use the result

Display text, set an image src, parse JSON, or append to FormData for upload.

📝 Notes

  • accept on the input filters the picker UI but can be bypassed—always validate in code.
  • multiple attribute allows selecting many files; loop over files or use [...files].
  • Reset the input with fileInput.value = "" so the same file can be picked again.
  • FileReader is one-shot; create a new instance or call another read method for the next file.
  • Node.js fs.readFile / fs.promises.readFile run on the server, not in the browser tab.
  • For downloads, combine new Blob([data]) with a temporary <a download> link.

Browser Support

The File API and FileReader are widely supported in all modern browsers. Promise helpers like Blob.prototype.text() arrived later—check targets if you support very old engines.

Baseline · File API

File API &amp; FileReader

Supported in Chrome, Firefox, Safari, Edge, and current mobile browsers. Internet Explorer 10+ had partial FileReader support; IE is obsolete for new projects.

98% Modern browser support
Google Chrome All versions · Desktop & Mobile
Full support
Mozilla Firefox All versions · Desktop & Mobile
Full support
Apple Safari All versions · macOS & iOS
Full support
Microsoft Edge All versions · Chromium & Legacy
Full support
Internet Explorer IE 6+ · Legacy environments
Full support
Opera All modern versions
Full support
FileReader Excellent

Bottom line: Safe for production web apps targeting evergreen browsers. Use feature detection (if (window.FileReader)) only if you must support legacy embedded WebViews.

Conclusion

JavaScript file handling in the browser starts with user-selected files, continues with metadata checks, and finishes by reading contents through FileReader or modern promise helpers. With validation and error handlers in place, you can build previews, importers, and upload flows that feel instant and trustworthy.

Practice the five examples above, then explore array and string methods to process the text you read from files.

💡 Best Practices

✅ Do

  • Validate size and type before reading large files
  • Show loading and error messages to the user
  • Revoke blob URLs when previews are replaced
  • Use accept to guide users toward the right format
  • Re-validate uploads on the server

❌ Don’t

  • Trust client-only checks for security
  • Assume file.type is always accurate
  • Read huge files into memory without limits
  • Log sensitive file contents in production
  • Expect to write arbitrary paths on the user’s disk from the browser

Key Takeaways

Knowledge Unlocked

Five things to remember about file handling

Your foundation for client-side files in JavaScript.

5
Core concepts
📄 02

Metadata

name, size, type.

Inspect
📖 03

Read text

readAsText.

Content
🖼 04

Preview

readAsDataURL.

Images
05

Validate

Size + type checks.

Safety

❓ Frequently Asked Questions

No. In the browser, JavaScript can only access files the user explicitly selects through an input type=file element, drag-and-drop, or the File System Access API (where supported). It cannot browse arbitrary folders on the disk.
A File object represents the selected file (name, size, type). FileReader is a helper that reads the File contents asynchronously and delivers the result through onload, onerror, and onabort events.
Use readAsText (or the modern file.text() promise) for plain text files like .txt, .csv, or .json. Use readAsDataURL when you need a base64 data URL—most often to preview images in an img src attribute.
Not to arbitrary paths on the user's disk. You can trigger downloads with Blob and URL.createObjectURL, or use the File System Access API in supported browsers when the user grants save permission. Server-side Node.js uses fs to read and write on the server.
Check file.size and file.type (MIME) in your change handler before reading. Use the accept attribute on the input to hint allowed types, but always re-validate because accept is not a security boundary.
Blob URLs stay in memory until revoked. After you finish previewing or downloading, call URL.revokeObjectURL(url) to free memory—especially important when users pick many files in one session.
Did you know?

Every File is also a Blob, so you can pass it directly to fetch bodies, FormData.append, or URL.createObjectURL without reading it into a string first.

Continue to Array

Master built-in array helpers for sorting, filtering, and transforming the data you read from files.

Array tutorial →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

6 people found this page helpful