File System Standard File System Living Standard — Last Updated 15 March 2026 Participate: GitHub whatwg/fs (new issue, open issues) Chat on Matrix Commits: GitHub whatwg/fs/commits Snapshot as of this commit @whatfilesystem Tests: web-platform-tests fs/ (ongoing work) Translat…
File System Standard File System Living Standard — Last Updated 15 March 2026 Participate: GitHub whatwg/fs (new issue, open issues) Chat on Matrix Commits: GitHub whatwg/fs/commits Snapshot as of this commit @whatfilesystem Tests: web-platform-tests fs/ (ongoing work) Translations (non-normative): 日本語 简体中文 한국어 Abstract File System defines infrastructure for file systems as well as their API. 1. Introduction This section is non-normative. This document defines fundamental infrastructure for file system APIs. In addition, it defines an API that makes it possible for websites to get access to a file system directory without having to first prompt the user for access. This enables use cases where a website wants to save data to disk before a user has picked a location to save to, without forcing the website to use a completely different storage mechanism with a different API for such files. The entry point for this is the navigator.storage.getDirectory() method. 2. Files and Directories 2.1. Concepts A file system entry is either a file entry or a directory entry. Each file system entry has an associated query access algorithm, which takes "read" or "readwrite" mode and returns a file system access result. Unless specified otherwise it returns a file system access result with a permission state of "denied" and with an error name of the empty string. Each file system entry has an associated request access algorithm, which takes "read" or "readwrite" mode and returns a file system access result. Unless specified otherwise it returns a file system access result with a permission state of "denied" and with an error name of the empty string. A file system access result is a struct encapsulating the result of querying or requesting access to the file system. It has the following items: permission state A PermissionState error name A string which must be the empty string if permission state is "granted"; otherwise an name listed in the DOMException names table. It is expected that in most cases when permission state is not "granted", this should be "NotAllowedError". Dependent specifications may consider this API a powerful feature. However, unlike other powerful features whose permission request algorithm may throw, file system entry’s query access and request access algorithms must run in parallel on the file system queue and are therefore not allowed to throw. Instead, the caller is expected to queue a storage task to reject, as appropriate, should these algorithms return an error name other than the empty string. Note: Implementations that only implement this specification and not dependent specifications do not need to bother implementing file system entry’s query access and request access. Make access check algorithms associated with a FileSystemHandle. [Issue #101] Each file system entry has an associated name (a string). A valid file name is a string that is not an empty string, is not equal to "." or "..", and does not contain '/' or any other character used as path separator on the underlying platform. Note: This means that '\' is not allowed in names on Windows, but might be allowed on other operating systems. Additionally underlying file systems might have further restrictions on what names are or aren’t allowed, so a string merely being a valid file name is not a guarantee that creating a file or directory with that name will succeed. We should consider having further normative restrictions on file names that will never be allowed using this API, rather than leaving it entirely up to underlying file systems. A file entry additionally consists of binary data (a byte sequence), a modification timestamp (a number representing the number of milliseconds since the Unix Epoch), a lock (a string that may exclusively be "open", "taken-exclusive" or "taken-shared") and a shared lock count (a number representing the number shared locks that are taken at a given point in time). A user agent has an associated file system queue which is the result of starting a new parallel queue. This queue is to be used for all file system operations. To take a lock with a value of "exclusive" or "shared" on a given file entry file: Let lock be the file’s lock. Let count be the file’s shared lock count. If value is "exclusive": If lock is "open": Set lock to "taken-exclusive". Return "success". If value is "shared": If lock is "open": Set lock to "taken-shared". Set count to 1. Return "success". Otherwise, if lock is "taken-shared": Increase count by 1. Return "success". Return "failure". Note: These steps have to be run on the file system queue. To release a lock on a given file entry file: Let lock be the file’s associated lock. Let count be the file’s shared lock count. If lock is "taken-shared": Decrease count by 1. If count is 0, set lock to "open". Otherwise, set lock to "open". Note: These steps have to be run on the file system queue. Note: Locks help prevent concurrent modifications to a file. A FileSystemWritableFileStream requires a shared lock, while a FileSystemSyncAccessHandle requires an exclusive one. A directory entry additionally consists of a set of children, which are themselves file system entries. Each member is either a file entry or a directory entry. A file system entry entry should be contained in the children of at most one directory entry, and that directory entry is also known as entry’s parent. A file system entry’s parent is null if no such directory entry exists. Note: Two different file system entries can represent the same file or directory on disk, in which case it is possible for both entries to have a different parent, or for one entry to have a parent while the other entry does not have a parent. File system entries can (but don’t have to) be backed by files on the host operating system’s local file system, so it is possible for the binary data, modification timestamp, and children of entries to be modified by applications outside of this specification. Exactly how external changes are reflected in the data structures defined by this specification, as well as how changes made to the data structures defined here are reflected externally is left up to individual user-agent implementations. A file system entry a is the same entry as a file system entry b if a is equal to b, or if a and b are backed by the same file or directory on the local file system. To resolve a file system locator child relative to a directory locator root: Let result be a new promise. Enqueue the following steps to the file system queue: If child’s locator’s root is not root’s locator’s root, resolve result with null, and abort these steps. Let childPath be child’s locator’s path. Let rootPath be root’s locator’s path. If childPath is the same path as rootPath, resolve result with « », and abort these steps. If rootPath’s size is greater than childPath’s size, resolve result with null, and abort these steps. For each index of rootPath’s indices: If rootPath.[[index]] is not childPath.[[index]], then resolve result with null, and abort these steps. Let relativePath be « ». For each index of the range from rootPath’s size to rootPath’s size, exclusive, append childPath.[[index]] to relativePath. Resolve result with relativePath. Return result. A file system locator represents a potential location of a file system entry. A file system locator is either a file locator or a directory locator. Each file system locator has an associated path (a file system path), a kind (a FileSystemHandleKind), and a root (a file system root). Consider giving each locator a storage bucket. [Issue #109] A file locator is a file system locator whose kind is "file". A directory locator is a file system locator whose kind is "directory". A file system root is an opaque string whose value is implementation-defined. For a file system locator locator whichs locates to a file entry entry that conceptually exists at the path data/drafts/example.txt relative to the root directory of a bucket file system, locator’s kind has to be "file", locator’s path has to be « "data", "drafts", "example.txt" », and locator’s root might include relevant identifying information such as the storage bucket and the disk drive. A file system locator a is the same locator as a file system locator b if a’s kind is b’s kind, a’s root is b’s root, and a’s path is the same path as b’s path. The locate an entry algorithm given a file system locator locator runs an implementation-defined series of steps adhering to these constraints: If locator is a file locator, they return a file entry or null. If locator is a directory locator, they return a directory entry or null. If these steps return a non-null entry, then: Getting the locator with entry returns locator, provided no intermediate file system operations were run. entry’s name is the last item of locator’s path. The get the locator algorithm given file system entry entry runs an implementation-defined series of steps adhering to these constraints: If entry is a file entry, they return a file locator. If entry is a directory entry, they return a directory locator. If these steps return locator, then: Locating an entry with locator returns entry, provided no intermediate file system operations were run. entry’s name is the last item of locator’s path. A file system path is a list of one or more strings. This may be a virtual path that is mapped to real location on disk or in memory, may correspond directly to a path on the local file system, or may not correspond to any file on disk at all. The actual physical location of the corresponding file system entry is implementation-defined. Let path be the list « "data", "drafts", "example.txt" ». There is no expectation that a file named example.txt exists anywhere on disk. A file system path a is the same path as a file system path b if a’s size is the same as b’s size and for each index of a’s indices a.[[index]] is b.[[index]]. The contents of a file system locator, including its path, are not expected to be shared in their entirety with the website process. The file system path might contain components which are not known to the website unless the file system locator is later resolved relative to a parent directory locator. 2.2. The FileSystemHandle interface enum FileSystemHandleKind { "file", "directory", }; [Exposed=(Window,Worker), SecureContext, Serializable] interface FileSystemHandle { readonly attribute FileSystemHandleKind kind; readonly attribute USVString name; Promise<boolean> isSameEntry(FileSystemHandle other); }; A FileSystemHandle object is associated with a locator (a file system locator). Note: Multiple FileSystemHandle objects can have the same file system locator. A FileSystemHandle is in a bucket file system if the first item of its locator’s path is the empty string. Note: This is a bit magical, but it works since only the root directory of a bucket file system can have a path which contains an empty string. See getDirectory(). All other items of a path will be a valid file name. Consider improving this situation by giving each locator a storage bucket. [Issue #109] FileSystemHandle objects are serializable objects. Their serialization steps, given value, serialized and forStorage are: Set serialized.[[Origin]] to value’s relevant settings object’s origin. Set serialized.[[Locator]] to value’s locator. Their deserialization steps, given serialized and value are: If serialized.[[Origin]] is not same origin with value’s relevant settings object’s origin, then throw a "DataCloneError" DOMException. Set value’s locator to serialized.[[Locator]]. handle . kind Returns "file" if handle is a FileSystemFileHandle, or "directory" if handle is a FileSystemDirectoryHandle. This can be used to distinguish files from directories when iterating over the contents of a directory. handle . name Returns the last path com…