How Chromium's File System Access API Reads and Writes Files

This article provides a complete overview of how the File System Access API in Chromium-based browsers enables web applications to interact directly with a user's local files and folders. It covers the core mechanics of file and directory handles, the step-by-step process of reading and writing data directly to the disk, the mandatory user-driven permission prompts, and the built-in security restrictions that protect the local operating system from malicious access.

The Core Mechanism: File and Directory Handles

Traditional web browsers isolate web applications from the local operating system, limiting file interactions to basic uploads and downloads. The File System Access API bridges this gap by introducing "handles"—specifically FileSystemFileHandle and FileSystemDirectoryHandle.

Instead of simply giving the browser a one-time copy of a file, a handle acts as a direct reference pointer to the actual file or directory residing on the user's hard drive. Once a web application holds a handle, it can repeatedly read from or write to that specific location without requiring the user to re-upload or re-download the data.

Initiating Access and the First Permission Prompt

Web applications cannot silently scan or access a user's hard drive. Every interaction using the File System Access API must be initiated by a direct user gesture, such as clicking a button.

When the user clicks to open a file or folder, the web app calls one of three global methods:

  • window.showOpenFilePicker() to read existing files.
  • window.showSaveFilePicker() to create a new file or overwrite an existing one.
  • window.showDirectoryPicker() to access an entire folder.

Calling any of these methods opens the operating system’s native file picker dialog. This native dialog serves as the first permission barrier. The web application gains no access until the user explicitly selects a file or folder and confirms their choice.

Reading Files and Folders

When a user selects a file or directory through the native picker, they implicitly grant the web application read access.

To read a single file, the application calls the getFile() method on the returned FileSystemFileHandle. This provides a standard File object, which the web app can read as text, an array buffer, or a data stream.

If the user selects a folder using showDirectoryPicker(), the application receives a FileSystemDirectoryHandle. The web app can then iterate through the contents of this local folder, reading all nested files and subdirectories inside it. If the user modifies a file on their computer using another program while the web app is open, the web app can call getFile() again on the handle to read the newly updated data instantly.

Writing Data and the Second Permission Prompt

Writing data directly to the local disk requires elevated privileges. Unless the user initially used showSaveFilePicker() (which implies an intent to write), Chromium enforces a second, explicit permission prompt before any changes can be saved.

When the web application attempts to modify a file or create a new file inside an opened directory, the browser pauses the execution and displays a prompt at the top of the screen. This prompt asks the user if they want to allow the specific website to "edit files" or "save changes" to the selected file or folder.

Once the user clicks "Allow," the writing process happens through the following steps:

  1. Create a Stream: The application calls createWritable() on the file handle, which generates a FileSystemWritableFileStream object.
  2. Write to a Temporary File: As the web app writes data to this stream, Chromium does not immediately overwrite the user's actual file. Instead, it writes the new data to a hidden, temporary swap file on the disk. This prevents data corruption if the browser crashes or the web app malfunctions mid-write.
  3. Security Checks and Commit: The changes are only finalized when the application calls the close() method on the stream. At this exact moment, Chromium runs its Safe Browsing malware checks on the temporary file. If the file passes the security check, the temporary file replaces the original local file.

Security Restrictions and Session Persistence

Even with user consent, the File System Access API does not grant absolute access to the hard drive. Chromium maintains a strict blocklist of sensitive operating system directories. If a user attempts to grant a web app access to critical folders—such as the Windows directory, macOS System or Library folders, or the Linux /etc directory—the browser will block the request and refuse to return a handle.

By default, all read and write permissions are tied to the lifecycle of the browser tab. Once the user closes the tab, the web application loses access to the local folders. However, web apps can save FileSystemHandle objects inside the browser's IndexedDB storage. When the user returns to the website in a future session, the app can retrieve the stored handle and call requestPermission(). This triggers a simple browser prompt asking the user to restore access to the previously selected folder, bypassing the need to navigate the OS file picker again.