Skip to content

Origin Private File System (OPFS)

Published

In one line: Per MDN, “the origin private file system (OPFS) is a storage endpoint provided as part of the File System API, which is private to the origin of the page and not visible to the user like the regular file system,” offering “in-place write access to its content.”

How it differs from the user-visible file system

Section titled “How it differs from the user-visible file system”

MDN summarizes several distinctions from the File System Access API’s user-visible files: the OPFS “is subject to browser storage quota restrictions, just like any other origin-partitioned storage mechanism (for example IndexedDB API)”; its usage can be inspected via navigator.storage.estimate(); “clearing storage data for the site deletes the OPFS”; “permission prompts and security checks are not required to access files in the OPFS”; and “the OPFS is not intended to be visible to the user.” MDN also notes OPFS offers “low-level, byte-by-byte file access” and, because it skips the picker/permission security checks the user-visible File System Access API needs, “is therefore faster.”

const opfsRoot = await navigator.storage.getDirectory();
const fileHandle = await opfsRoot.getFileHandle("my-file.txt", { create: true });

MDN states: “To access the OPFS in the first place, you call the navigator.storage .getDirectory() method. This returns a reference to a FileSystemDirectoryHandle object that represents the root of the OPFS.” From the main thread, files and directories are accessed with the asynchronous, Promise-based FileSystemDirectoryHandle.getFileHandle() and getDirectoryHandle(), and passing { create: true } “causes the file or folder to be created if it doesn’t exist.”

Synchronous access from a dedicated Web Worker

Section titled “Synchronous access from a dedicated Web Worker”

MDN explains that OPFS “also has a set of synchronous calls available (other File System API calls are asynchronous)” for better performance, and that the resulting FileSystemSyncAccessHandle “is only accessible inside dedicated Web Workers” so its synchronous methods do not block execution on the main thread. Despite the name, MDN notes “the createSyncAccessHandle() method itself is asynchronous”:

// Inside a dedicated Web Worker
const opfsRoot = await navigator.storage.getDirectory();
const fileHandle = await opfsRoot.getFileHandle("fast", { create: true });
const accessHandle = await fileHandle.createSyncAccessHandle();
const content = new TextEncoder().encode("Some text");
accessHandle.write(content, { at: 0 });
accessHandle.flush();
accessHandle.close();

MDN lists the synchronous methods on the resulting FileSystemSyncAccessHandle: getSize() (“returns the size of the file in bytes”), write() (“writes the content of a buffer into the file, optionally at a given offset, and returns the number of written bytes”), read() (“reads the contents of the file into a buffer, optionally at a given offset”), truncate() (“resizes the file to the given size”), flush() (“ensures that the file contents contain all the modifications done through write()”), and close() (“closes the access handle”).

async function openOpfsFile(name) {
if (!("storage" in navigator) || !("getDirectory" in navigator.storage)) {
// OPFS unsupported here — fall back to IndexedDB or in-memory storage.
return null;
}
const opfsRoot = await navigator.storage.getDirectory();
return opfsRoot.getFileHandle(name, { create: true });
}

MDN marks OPFS Baseline: Widely available, noting “it’s been available across browsers since March 2023.” MDN also flags it as a secure-context feature (“available only in secure contexts (HTTPS), in some or all supporting browsers”). The synchronous FileSystemSyncAccessHandle methods specifically are, per MDN, “only accessible inside dedicated Web Workers.”

  • Feature-detect navigator.storage?.getDirectory before use, even though MDN marks OPFS Baseline widely available since March 2023 — older or non-browser environments may lack it.
  • Serve the page over HTTPS; MDN documents OPFS as a secure-context-only feature.
  • Use the synchronous FileSystemSyncAccessHandle methods (read(), write(), flush(), close()) only inside a dedicated Web Worker — MDN states this class “is only accessible inside dedicated Web Workers” so its methods do not block the main thread. Shared workers and service workers are not supported.
  • Remember createSyncAccessHandle() itself returns a Promise despite its name, per MDN.
  • Don’t expect OPFS content to be visible to the user or to survive a “clear storage data” action — MDN states clearing site storage deletes the OPFS and that it “is not intended to be visible to the user.”
  • Budget for browser storage quota limits, since MDN says OPFS “is subject to browser storage quota restrictions, just like any other origin-partitioned storage mechanism.”