# Virtual File System > Stability: 1 - Experimental The `node:vfs` module provides a virtual file system with a `node:fs`-like API. It is useful for tests, fixtures, embedded assets, and other scenarios where you need a self-contained file system without touching the actual file-system. To access it: ```mjs import vfs from 'node:vfs'; ``` ```cjs const vfs = require('node:vfs'); ``` This module is only available under the `node:` scheme, and only when Node.js is started with the `--experimental-vfs` flag. ## Security The VFS API is not a sandbox, permission system, or access-control mechanism. It does not isolate untrusted code from the host file system or from other Node.js capabilities. Code that can access a [`VirtualFileSystem`][] instance, mount it, select its provider, or pass paths to it is trusted application code. Mounting a VFS only redirects supported [`node:fs`][] calls whose resolved paths are under the mount point. It does not prevent code from using other paths or other Node.js APIs to access resources available to the process. [`RealFSProvider`][] maps VFS paths under its configured root and rejects paths that resolve outside that root, but that check is not a security boundary. Do not rely on VFS to run untrusted code; use operating-system-level isolation, such as separate users, containers, or platform sandboxes, when a security boundary is required. ## Basic usage ```cjs const vfs = require('node:vfs'); const myVfs = vfs.create(); myVfs.mkdirSync('/dir', { recursive: true }); myVfs.writeFileSync('/dir/hello.txt', 'Hello, VFS!'); console.log(myVfs.readFileSync('/dir/hello.txt', 'utf8')); // 'Hello, VFS!' ``` `vfs.create()` returns a [`VirtualFileSystem`][] instance backed by a [`MemoryProvider`][] by default. The instance exposes synchronous, callback-based, and promise-based file system methods that mirror the shape of the [`node:fs`][] API. All paths are POSIX-style and absolute (starting with `/`). ## `vfs.create([provider][, options])` * `provider` {VirtualProvider} The provider to use. **Default:** `new MemoryProvider()`. * `options` {Object} * `emitExperimentalWarning` {boolean} Whether to emit the experimental warning when the instance is created. **Default:** `true`. * Returns: {VirtualFileSystem} Convenience factory equivalent to `new VirtualFileSystem(provider, options)`. ```cjs const vfs = require('node:vfs'); // Default in-memory provider const memoryVfs = vfs.create(); // Explicit provider const realVfs = vfs.create(new vfs.RealFSProvider('/tmp/vfs-root')); ``` ## Class: `VirtualFileSystem` A `VirtualFileSystem` wraps a [`VirtualProvider`][] and exposes a `node:fs`-like API. Each instance maintains its own file tree. ### `new VirtualFileSystem([provider][, options])` * `provider` {VirtualProvider} The provider to use. **Default:** `new MemoryProvider()`. * `options` {Object} * `emitExperimentalWarning` {boolean} Whether to emit the experimental warning. **Default:** `true`. ### `vfs.provider` * {VirtualProvider} The provider backing this VFS instance. ### `vfs.readonly` * {boolean} `true` when the underlying provider is read-only. ### APIs `VirtualFileSystem` implements the following methods, with the same signatures as their [`node:fs`][] counterparts: #### Synchronous API * `existsSync(path)` * `statSync(path[, options])` * `lstatSync(path[, options])` * `readFileSync(path[, options])` * `writeFileSync(path, data[, options])` * `appendFileSync(path, data[, options])` * `readdirSync(path[, options])` * `mkdirSync(path[, options])` * `rmdirSync(path)` * `unlinkSync(path)` * `renameSync(oldPath, newPath)` * `copyFileSync(src, dest[, mode])` * `realpathSync(path[, options])` * `readlinkSync(path[, options])` * `symlinkSync(target, path[, type])` * `accessSync(path[, mode])` * `rmSync(path[, options])` * `truncateSync(path[, len])` * `ftruncateSync(fd[, len])` * `linkSync(existingPath, newPath)` * `chmodSync(path, mode)` * `chownSync(path, uid, gid)` * `lchownSync(path, uid, gid)` * `utimesSync(path, atime, mtime)` * `lutimesSync(path, atime, mtime)` * `mkdtempSync(prefix)` * `opendirSync(path[, options])` * `openAsBlob(path[, options])` * File-descriptor ops: `openSync`, `closeSync`, `readSync`, `writeSync`, `fstatSync` * Streams: `createReadStream`, `createWriteStream` * Watchers: `watch`, `watchFile`, `unwatchFile` #### Callback API `readFile`, `writeFile`, `stat`, `lstat`, `readdir`, `realpath`, `readlink`, `access`, `open`, `close`, `read`, `write`, `rm`, `fstat`, `truncate`, `ftruncate`, `link`, `mkdtemp`, `opendir`. Each takes a Node.js-style callback `(err, ...result) => {}`. #### Promise API `vfs.promises` exposes the promise-based variants: ```cjs const vfs = require('node:vfs'); async function example() { const myVfs = vfs.create(); await myVfs.promises.writeFile('/file.txt', 'hello'); const data = await myVfs.promises.readFile('/file.txt', 'utf8'); return data; } example(); ``` The promise namespace mirrors `fs.promises` and includes `readFile`, `writeFile`, `appendFile`, `stat`, `lstat`, `readdir`, `mkdir`, `rmdir`, `unlink`, `rename`, `copyFile`, `realpath`, `readlink`, `symlink`, `access`, `rm`, `truncate`, `link`, `mkdtemp`, `chmod`, `chown`, `lchown`, `utimes`, `lutimes`, `open`, `lchmod`, and `watch`. ## Class: `VirtualProvider` The base class for all VFS providers. Subclasses implement the essential primitives (such as `open`, `stat`, `readdir`, `mkdir`, `rmdir`, `unlink`, `rename`, etc.) and inherit default implementations of the derived methods (such as `readFile`, `writeFile`, `exists`, `copyFile`, `access`, etc.). ### Capability flags * `provider.readonly` {boolean} **Default:** `false`. * `provider.supportsSymlinks` {boolean} **Default:** `false`. * `provider.supportsWatch` {boolean} **Default:** `false`. ### Creating custom providers ```cjs const { VirtualProvider } = require('node:vfs'); class StaticProvider extends VirtualProvider { get readonly() { return true; } statSync(path) { /* ... */ } openSync(path, flags) { /* ... */ } readdirSync(path, options) { /* ... */ } // ... } ``` The base class throws `ERR_METHOD_NOT_IMPLEMENTED` for any primitive that has not been overridden, and rejects writes from a `readonly` provider with `EROFS`. ## Class: `MemoryProvider` The default in-memory provider. Stores files, directories, and symbolic links in a `Map`-backed tree, supports symlinks (`supportsSymlinks === true`), and supports watching (`supportsWatch === true`). ### `memoryProvider.setReadOnly()` Locks the provider into read-only mode. Subsequent writes through any [`VirtualFileSystem`][] using this provider throw `EROFS`. There is no way to revert the provider to writable. ```cjs const vfs = require('node:vfs'); const provider = new vfs.MemoryProvider(); const myVfs = vfs.create(provider); myVfs.writeFileSync('/seed.txt', 'initial'); provider.setReadOnly(); myVfs.writeFileSync('/x.txt', 'fail'); // throws EROFS ``` ## Class: `RealFSProvider` A provider that wraps a directory (i.e. one on the actual file system) and exposes its contents through the VFS API. All VFS paths are resolved relative to the root and verified to stay inside it; symbolic links resolving outside the root are rejected. This path mapping is not a sandbox or access-control mechanism. ### `new RealFSProvider(rootPath)` * `rootPath` {string} The absolute file-system path to use as the root. Must be a non-empty string. ```cjs const vfs = require('node:vfs'); const realVfs = vfs.create(new vfs.RealFSProvider('/tmp/vfs-root')); realVfs.writeFileSync('/file.txt', 'hello'); // writes /tmp/vfs-root/file.txt ``` ### `realFSProvider.rootPath` * {string} The resolved absolute path used as the root. ## Implementation details ### `Stats` objects VFS `Stats` objects are real instances of [`fs.Stats`][] (or [`fs.BigIntStats`][] when `{ bigint: true }` is requested). Their fields use synthetic but stable values: * `dev` is `4085` (the VFS device id). * `ino` is monotonically increasing per process. * `blksize` is `4096`. * `blocks` is `Math.ceil(size / 512)`. * Times default to the moment the entry was created/last modified. [`MemoryProvider`]: #class-memoryprovider [`RealFSProvider`]: #class-realfsprovider [`VirtualFileSystem`]: #class-virtualfilesystem [`VirtualProvider`]: #class-virtualprovider [`fs.BigIntStats`]: fs.md#class-fsbigintstats [`fs.Stats`]: fs.md#class-fsstats [`node:fs`]: fs.md