Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
116 commits
Select commit Hold shift + click to select a range
cc08a06
fs: add virtual file system support
mcollina Jan 22, 2026
7eabec2
vfs: add Windows path compatibility
mcollina Jan 23, 2026
c363709
sea: support VFS in embedderRequire
mcollina Jan 23, 2026
8b1aa8f
test: add tmpdir.refresh() to SEA VFS test
mcollina Jan 24, 2026
9a4e1b6
test: update SEA VFS test for new buildSEA API
mcollina Jan 25, 2026
43adc6b
vfs: add provider-based architecture and node:vfs module
mcollina Jan 27, 2026
4fe1158
vfs: remove backward compat methods, use standard fs API
mcollina Jan 27, 2026
83f4fe7
vfs: address review comments
mcollina Jan 27, 2026
402a81c
vfs: fix lint errors
mcollina Jan 28, 2026
0f3e763
vfs: fix lint errors
mcollina Jan 28, 2026
54af709
vfs: remove public createSEA()
mcollina Jan 28, 2026
29c0418
vfs: address review comments
mcollina Jan 28, 2026
91bfe25
doc: address review comments on VFS documentation
mcollina Jan 28, 2026
3c5211d
doc: clarify virtualCwd behavior in Worker threads
mcollina Jan 28, 2026
37300a1
vfs: add RealFSProvider for mounting real directories
mcollina Jan 28, 2026
a7b5862
tools: add VFS types to doc type-parser
mcollina Jan 28, 2026
3fac286
doc: use REPLACEME for version placeholders in vfs.md
mcollina Jan 29, 2026
86cb0a6
doc: add security warnings and symlink documentation to vfs.md
mcollina Jan 29, 2026
9e8479b
vfs: address code review feedback from @jasnell
mcollina Jan 29, 2026
fab4453
vfs: add overlay mode for selective file interception
mcollina Jan 29, 2026
c035802
vfs: add tests and fix appendFile, add readonly checks
mcollina Jan 30, 2026
f46855c
fs: remove createVirtual, use node:vfs instead
mcollina Jan 31, 2026
1ee25ca
vfs: add watch and watchFile support
mcollina Jan 31, 2026
897b989
vfs: improve test coverage for watch implementation
mcollina Jan 31, 2026
2266ac1
vfs: remove unused utility functions from module_hooks
mcollina Jan 31, 2026
0585518
vfs: add test for symlink target creation after symlink
mcollina Feb 1, 2026
d5cf2b6
doc: add worker thread limitations to VFS documentation
mcollina Feb 1, 2026
334f017
doc: clarify VFS accepts same types as fs module
mcollina Feb 1, 2026
81d1395
vfs: remove unused entries.js, add error tests
mcollina Feb 1, 2026
bade36a
vfs: remove unused exports from fd.js and stats.js
mcollina Feb 1, 2026
da96b9f
vfs: remove unused VirtualFD methods
mcollina Feb 1, 2026
65f4e6f
vfs: remove more unused VirtualFD code
mcollina Feb 1, 2026
549d9d7
vfs: address Aviv's review comments
mcollina Feb 2, 2026
799b773
test: improve VFS code coverage
mcollina Feb 2, 2026
af3aabe
Update lib/internal/vfs/module_hooks.js
mcollina Feb 2, 2026
b03e338
Update lib/internal/vfs/module_hooks.js
mcollina Feb 2, 2026
9b37b32
vfs: address aduh95 review comments
mcollina Feb 2, 2026
42a0813
vfs: remove SEAProvider export and hasSeaAssets
mcollina Feb 3, 2026
33b9e9c
vfs: remove addFile and addDirectory methods
mcollina Feb 3, 2026
e4f943e
doc: alphabetize VirtualFileSystem members in vfs.md
mcollina Feb 3, 2026
62067f4
Update single-executable-applications.md
mcollina Feb 3, 2026
c88b5ad
sea: remove getVfs from public API
mcollina Feb 3, 2026
f6ea36b
doc: explain symlink behavior in overlay mode
mcollina Feb 3, 2026
63e2519
doc: document overlay mode behavior for fs operations
mcollina Feb 3, 2026
51dca9d
vfs: add Symbol.dispose support for automatic unmount
mcollina Feb 3, 2026
d818dd1
vfs: add missing JSDoc @returns for mount()
mcollina Feb 3, 2026
5f36f6e
vfs: only initialize SEA VFS when assets exist
mcollina Feb 3, 2026
87804ee
vfs: use path.posix methods instead of custom implementations
mcollina Feb 4, 2026
f39028e
vfs: address review feedback for SEA docs and getSeaVfs
mcollina Feb 4, 2026
8d61b19
vfs: refactor SEA VFS with initSeaVfs/getSeaVfs pattern
mcollina Feb 5, 2026
1267775
vfs: address test review feedback
mcollina Feb 5, 2026
fc13205
vfs: replace custom path helpers with standard path module
mcollina Feb 5, 2026
187ca4e
vfs: address remaining review feedback from avivkeller
mcollina Feb 5, 2026
5044cfd
test: expand VFS provider and promises test coverage
mcollina Feb 6, 2026
a7600be
fixup! test: expand VFS provider and promises test coverage
mcollina Feb 10, 2026
7cbc649
doc: address vfs documentation review feedback
mcollina Feb 10, 2026
a3ec3dd
test: add Windows-specific VFS mount path tests
mcollina Feb 10, 2026
a440080
vfs: address code review feedback
mcollina Feb 10, 2026
206c7fe
vfs: add process vfs-mount and vfs-unmount events
mcollina Feb 11, 2026
29818ec
vfs: address code review feedback
mcollina Feb 12, 2026
b80ea83
doc: add case sensitivity documentation for VFS overlay mode
mcollina Feb 12, 2026
40bbe99
sea: use wrapModuleLoad for VFS module loading
mcollina Feb 13, 2026
2115076
doc: add VFS limitations and cross-references
mcollina Feb 13, 2026
c79c99a
vfs: fix path normalization on Windows
mcollina Feb 13, 2026
ef1ead1
sea,vfs: address review feedback from Joyee
mcollina Feb 18, 2026
d4c4d26
test: use relative require in SEA VFS test
mcollina Feb 18, 2026
a893956
sea,vfs: fix C++ formatting and markdown link ordering
mcollina Feb 18, 2026
ff93075
doc: address Joyee's documentation review feedback
mcollina Feb 19, 2026
d79511a
sea,vfs: address Joyee's code review feedback
mcollina Feb 19, 2026
8923b94
test: add buffer independence and SEA VFS coverage tests
mcollina Feb 19, 2026
cd4e861
sea: fix C++ compilation errors in Initialize
mcollina Feb 19, 2026
7b9734a
vfs: replace fs patching with toggleable toRealPath for module loading
mcollina Feb 20, 2026
0b279c4
vfs: extend toggleable wrappers to readFileSync and internalModuleStat
mcollina Feb 22, 2026
5703cbc
vfs: make package.json reader VFS-aware
mcollina Feb 23, 2026
0ed9884
vfs: convert underscore-prefixed methods to private class fields
mcollina Feb 24, 2026
1965689
test: add missing callback tests for VFS promises test file
mcollina Feb 24, 2026
5ed245c
vfs: lazy-load esm/formats to fix shared library builds
mcollina Feb 24, 2026
2f5c616
test: add VFS bare specifier ESM resolution test
mcollina Feb 25, 2026
f6a87eb
vfs: replace monkeypatching with self-contained module.registerHooks
mcollina Feb 25, 2026
74e002d
test: add comprehensive VFS module hooks coverage tests
mcollina Feb 25, 2026
53f57c7
vfs: address review feedback for module_hooks and file_system
mcollina Feb 26, 2026
5b6e3d1
test: use descriptive mount paths in VFS ESM import tests
mcollina Feb 27, 2026
af8ed7f
test: add VFS internals coverage tests
mcollina Feb 27, 2026
17c4acb
Apply suggestions from code review
mcollina Mar 2, 2026
7ea0ad2
Apply suggestion from @aduh95
mcollina Mar 2, 2026
3f61858
Apply suggestions from code review
mcollina Mar 2, 2026
da9e560
doc: address aduh95 review feedback on VFS docs
mcollina Mar 2, 2026
17858bd
vfs: address aduh95 code review comments
mcollina Mar 2, 2026
ba5b1d3
vfs: restore isExperimentalSeaWarningNeeded as a function
mcollina Mar 2, 2026
ef8b1e9
vfs: revert non-VFS changes in cjs/loader.js and esm/resolve.js
mcollina Mar 3, 2026
2c9ae60
vfs: restore extensionless file format detection and test
mcollina Mar 3, 2026
fcd05a7
vfs: remove internalModuleStat from provider base class
mcollina Mar 3, 2026
79afe93
vfs: align lib/internal/modules/ with upstream main
mcollina Mar 3, 2026
d187d6e
vfs: restore isSea as function, align modules/ with upstream
mcollina Mar 3, 2026
a020fbb
vfs: restore sea.js to match upstream main
mcollina Mar 4, 2026
77c3c9a
vfs: use wrapModuleLoad for SEA VFS entry point
mcollina Mar 4, 2026
2285720
vfs: replace fs monkey-patching with toggleable loader wrappers
mcollina Mar 5, 2026
b64733f
vfs: address review feedback on path utilities and providers
mcollina Mar 5, 2026
79f4d6e
vfs: fix Windows path handling and remove wrapper functions
mcollina Mar 7, 2026
19a694f
vfs: fix lint warnings in router.js and test-vfs-chdir.js
mcollina Mar 8, 2026
cd7f836
vfs: document that useVfs does not support ESM entry points
mcollina Mar 9, 2026
5496a39
vfs: add VFS-aware wrappers for package.json reader methods
mcollina Mar 11, 2026
bafbf9c
vfs: remove vfs-mount and vfs-unmount process events
mcollina Mar 11, 2026
6a53f62
vfs: add require(esm) and ESM detection tests
mcollina Mar 11, 2026
7ed1fac
vfs: reject useVfs with useSnapshot, useCodeCache, or mainFormat module
mcollina Mar 13, 2026
abef360
vfs: move fs interception from monkey-patching into lib/fs.js
mcollina Mar 13, 2026
85685d0
vfs: remove duplicated module resolution logic from setup.js
mcollina Mar 13, 2026
84c1693
vfs: intercept all supported fs methods when VFS is mounted
mcollina Mar 13, 2026
219d7fe
vfs: increase test coverage and fix lint in destructuring test
mcollina Mar 13, 2026
523ffd1
vfs: add remaining fs method interceptions and openAsBlob support
mcollina Mar 13, 2026
54806bd
vfs: add remaining fs/promises VFS interceptions
mcollina Mar 14, 2026
f79ec2f
vfs: convert isVfsEnabled from property to method
mcollina Mar 15, 2026
220c430
vfs: add ESM loader intercepts for legacyMainResolve and getFormatOfE…
mcollina Mar 16, 2026
b894e3f
vfs: fix ESM legacyMainResolve tests to use bare specifier imports
mcollina Mar 16, 2026
8728a45
vfs: improve test coverage and add c8 ignore for SEA paths
mcollina Mar 16, 2026
2b95b97
vfs: address review comments on cp-sync and test docs
mcollina Mar 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions doc/api/fs.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,36 @@ try {
}
```

## Virtual File System (VFS) support

<!-- YAML
added: REPLACEME
-->

> Stability: 1 - Experimental

The `node:fs` module can operate on virtual files when the [`node:vfs`][] module is
used. When a virtual file system is mounted, `node:fs` operations on paths under
the mount point are automatically routed to the VFS instead of the real file
system.

```cjs
const vfs = require('node:vfs');
const fs = require('node:fs');

const myVfs = vfs.create();
myVfs.writeFileSync('/data.txt', 'Hello from VFS');
myVfs.mount('/virtual');

// This reads from the virtual file system
fs.readFileSync('/virtual/data.txt', 'utf8'); // 'Hello from VFS'

myVfs.unmount();
```
Comment on lines +137 to +149
Copy link
Member

@jasnell jasnell Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: add the parallel mjs examples

Suggested change
```cjs
const vfs = require('node:vfs');
const fs = require('node:fs');
const myVfs = vfs.create();
myVfs.writeFileSync('/data.txt', 'Hello from VFS');
myVfs.mount('/virtual');
// This reads from the virtual file system
fs.readFileSync('/virtual/data.txt', 'utf8'); // 'Hello from VFS'
myVfs.unmount();
```
```mjs
import * as vfs from 'node:vfs';
import * as fs from 'node:fs';
const myVfs = vfs.create();
myVfs.writeFileSync('/data.txt', 'Hello from VFS');
myVfs.mount('/virtual');
// This reads from the virtual file system
fs.readFileSync('/virtual/data.txt', 'utf8'); // 'Hello from VFS'
myVfs.unmount();
```
```cjs
const vfs = require('node:vfs');
const fs = require('node:fs');
const myVfs = vfs.create();
myVfs.writeFileSync('/data.txt', 'Hello from VFS');
myVfs.mount('/virtual');
// This reads from the virtual file system
fs.readFileSync('/virtual/data.txt', 'utf8'); // 'Hello from VFS'
myVfs.unmount();
```


Not all `node:fs` operations are supported with VFS. See the [`node:vfs`][]
documentation for the complete list of supported operations and limitations.

## Promises API

<!-- YAML
Expand Down Expand Up @@ -8787,6 +8817,7 @@ the file contents.
[`inotify(7)`]: https://man7.org/linux/man-pages/man7/inotify.7.html
[`kqueue(2)`]: https://www.freebsd.org/cgi/man.cgi?query=kqueue&sektion=2
[`minimatch`]: https://github.com/isaacs/minimatch
[`node:vfs`]: vfs.md
[`util.promisify()`]: util.md#utilpromisifyoriginal
[bigints]: https://tc39.github.io/proposal-bigint
[caveats]: #caveats
Expand Down
1 change: 1 addition & 0 deletions doc/api/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
* [URL](url.md)
* [Utilities](util.md)
* [V8](v8.md)
* [Virtual File System](vfs.md)
* [VM](vm.md)
* [WASI](wasi.md)
* [Web Crypto API](webcrypto.md)
Expand Down
81 changes: 81 additions & 0 deletions doc/api/single-executable-applications.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ The configuration currently reads the following top-level fields:
"disableExperimentalSEAWarning": true, // Default: false
"useSnapshot": false, // Default: false
"useCodeCache": true, // Default: false
"useVfs": true, // Default: false
"execArgv": ["--no-warnings", "--max-old-space-size=4096"], // Optional
"execArgvExtension": "env", // Default: "env", options: "none", "env", "cli"
"assets": { // Optional
Expand Down Expand Up @@ -175,6 +176,84 @@ const raw = getRawAsset('a.jpg');
See documentation of the [`sea.getAsset()`][], [`sea.getAssetAsBlob()`][],
[`sea.getRawAsset()`][] and [`sea.getAssetKeys()`][] APIs for more information.

### Virtual File System (VFS) for assets

<!-- YAML
added: REPLACEME
-->

> Stability: 1 - Experimental

In addition to using the `node:sea` API to access individual assets, you can use
the Virtual File System (VFS) to access bundled assets through standard `node:fs`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: the Virtual File System (VFS) here could be a link to that doc. But non-blocking

APIs. To enable VFS, set `"useVfs": true` in the SEA configuration. When
enabled, the VFS is automatically initialized and mounted at `/sea`. All
assets defined in the SEA configuration are accessible through this virtual
path.

```cjs
const fs = require('node:fs');

// Assets are automatically available at /sea when running as SEA
const rawConfig = fs.readFileSync('/sea/config.json', 'utf8');
const data = fs.readFileSync('/sea/data/file.txt');

const config = JSON.parse(rawConfig);

// Directory operations work too
const files = fs.readdirSync('/sea/assets');

// Check if a bundled file exists
if (fs.existsSync('/sea/optional.json')) {
// ...
}
```

The VFS supports all common `node:fs` operations for reading files and directories.
Since the SEA VFS is read-only, write operations are not supported. See the
[VFS documentation][] for the full list of supported and unsupported operations.

#### Loading modules from VFS in SEA

When `useVfs` is enabled, `require()` in the injected main script uses the
registered module hooks to load modules from the virtual file system. This
supports both absolute VFS paths and relative requires (e.g.,
`require('./helper.js')` from a VFS module), as well as `node_modules` package
lookups.

```cjs
// Require bundled modules using relative paths
const myModule = require('./lib/mymodule.js');
const utils = require('./utils/helpers.js');

// Absolute VFS paths also work
const config = require('/sea/config.json');
```

When `useVfs` is enabled, `__filename` and `__dirname` in the injected main
script reflect VFS paths (e.g., `/sea/main.js`) instead of
[`process.execPath`][].

#### ESM limitations

The `useVfs` option does not currently support ESM entry points. Using
`"useVfs": true` together with `"mainFormat": "module"` is not supported.
The main script must use CommonJS (`require()`) when VFS is enabled.

#### Code caching limitations

The `useCodeCache` option in the SEA configuration does not currently apply to
modules loaded from the VFS. This is a current limitation due to incomplete
implementation, not a technical impossibility. Consider bundling the application
to enable code caching and do not rely on module loading in VFS.

#### Native addon limitations

Native addons (`.node` files) cannot be loaded directly from the VFS because
`process.dlopen()` requires files on the real file system. To use native
addons in a SEA with VFS, write the asset to a temporary file first. See
[Using native addons in the injected main script][] for an example.

### Startup snapshot support

The `useSnapshot` field can be used to enable startup snapshot support. In this
Expand Down Expand Up @@ -647,6 +726,8 @@ to help us document them.
[Generating single executable preparation blobs]: #1-generating-single-executable-preparation-blobs
[Mach-O]: https://en.wikipedia.org/wiki/Mach-O
[PE]: https://en.wikipedia.org/wiki/Portable_Executable
[Using native addons in the injected main script]: #using-native-addons-in-the-injected-main-script
[VFS documentation]: vfs.md
[Windows SDK]: https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/
[`process.execPath`]: process.md#processexecpath
[`require()`]: modules.md#requireid
Expand Down
93 changes: 93 additions & 0 deletions doc/api/test.md
Original file line number Diff line number Diff line change
Expand Up @@ -2393,6 +2393,98 @@ test('mocks a counting function', (t) => {
});
```

### `mock.fs([options])`

<!-- YAML
added: REPLACEME
-->

> Stability: 1.0 - Early development

* `options` {Object} Optional configuration options for the mock file system.
The following properties are supported:
* `prefix` {string} The mount point prefix for the virtual file system.
**Default:** `'/mock'`.
* `files` {Object} An optional object where keys are file paths (relative to
the VFS root) and values are the file contents. Contents can be strings,
Buffers, or functions that return strings/Buffers.
* Returns: {MockFSContext} An object that can be used to manage the mock file
system.

This function creates a mock file system using the [Virtual File System (VFS)][].
The mock file system is automatically cleaned up when the test completes.

## Class: `MockFSContext`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
## Class: `MockFSContext`
## Class: `MockFSContext`
<!-- YAML
added: REPLACEME
-->


<!-- YAML
added: REPLACEME
-->

The `MockFSContext` object is returned by `mock.fs()` and provides the
following methods and properties:

* `vfs` {VirtualFileSystem} The underlying VFS instance.
* `prefix` {string} The mount prefix.
* `addFile(path, content)` Adds a file to the mock file system.
* `addDirectory(path[, populate])` Adds a directory to the mock file system.
* `existsSync(path)` Checks if a path exists (path is relative to prefix).
* `restore()` Manually restores the file system to its original state.

The following example demonstrates how to create a mock file system for testing:

```js
const { test } = require('node:test');
const assert = require('node:assert');
const fs = require('node:fs');

test('reads configuration from mock file', (t) => {
const mockFs = t.mock.fs({
prefix: '/app',
files: {
'/config.json': JSON.stringify({ debug: true }),
'/data/users.txt': 'user1\nuser2\nuser3',
},
});

// Files are accessible via standard fs APIs
const config = JSON.parse(fs.readFileSync('/app/config.json', 'utf8'));
assert.strictEqual(config.debug, true);

// Check file existence
assert.strictEqual(fs.existsSync('/app/config.json'), true);
assert.strictEqual(fs.existsSync('/app/missing.txt'), false);

// Use mockFs.existsSync for paths relative to prefix
assert.strictEqual(mockFs.existsSync('/config.json'), true);
});

test('supports dynamic file content', (t) => {
let counter = 0;
const mockFs = t.mock.fs({ prefix: '/dynamic' });

mockFs.addFile('/counter.txt', () => {
counter++;
return String(counter);
});

// Each read calls the function
assert.strictEqual(fs.readFileSync('/dynamic/counter.txt', 'utf8'), '1');
assert.strictEqual(fs.readFileSync('/dynamic/counter.txt', 'utf8'), '2');
});

test('supports require from mock files', (t) => {
t.mock.fs({
prefix: '/modules',
files: {
'/math.js': 'module.exports = { add: (a, b) => a + b };',
},
});

const math = require('/modules/math.js');
assert.strictEqual(math.add(2, 3), 5);
});
```

### `mock.getter(object, methodName[, implementation][, options])`

<!-- YAML
Expand Down Expand Up @@ -4259,3 +4351,4 @@ Can be used to abort test subtasks when the test has been aborted.
[suite options]: #suitename-options-fn
[test reporters]: #test-reporters
[test runner execution model]: #test-runner-execution-model
[virtual file system (vfs)]: vfs.md
Loading
Loading