Skip to content

Virtual File System for Node.js#61478

Open
mcollina wants to merge 106 commits intonodejs:mainfrom
mcollina:vfs
Open

Virtual File System for Node.js#61478
mcollina wants to merge 106 commits intonodejs:mainfrom
mcollina:vfs

Conversation

@mcollina
Copy link
Member

@mcollina mcollina commented Jan 22, 2026

A first-class virtual file system module (node:vfs) with a provider-based architecture that integrates with Node.js's fs module and module loader.

Key Features

  • Provider Architecture - Extensible design with pluggable providers:

    • MemoryProvider - In-memory file system with full read/write support
    • SEAProvider - Read-only access to Single Executable Application assets
    • VirtualProvider - Base class for creating custom providers
  • Standard fs API - Uses familiar writeFileSync, readFileSync, mkdirSync instead of custom methods

  • Mount Mode - VFS mounts at a specific path prefix (e.g., /virtual), clear separation from real filesystem

  • Module Loading - require() and import work seamlessly from virtual files

  • SEA Integration - Assets automatically mounted at /sea when running as a Single Executable Application

  • Full fs Support - readFile, stat, readdir, exists, streams, promises, glob, symlinks

Example

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

// Create a VFS with default MemoryProvider
const myVfs = vfs.create();

// Use standard fs-like API
myVfs.mkdirSync('/app');
myVfs.writeFileSync('/app/config.json', '{"debug": true}');
myVfs.writeFileSync('/app/module.js', 'module.exports = "hello"');

// Mount to make accessible via fs module
myVfs.mount('/virtual');

// Works with standard fs APIs
const config = JSON.parse(fs.readFileSync('/virtual/app/config.json', 'utf8'));
const mod = require('/virtual/app/module.js');

// Cleanup
myVfs.unmount();

SEA Usage

When running as a Single Executable Application, bundled assets are automatically available:

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

// Assets are automatically mounted at /sea - no setup required
const config = fs.readFileSync('/sea/config.json', 'utf8');
const template = fs.readFileSync('/sea/templates/index.html', 'utf8');

Public API

const vfs = require('node:vfs');

vfs.create([provider][, options])  // Create a VirtualFileSystem
vfs.VirtualFileSystem              // The main VFS class
vfs.VirtualProvider                // Base class for custom providers
vfs.MemoryProvider                 // In-memory provider
vfs.SEAProvider                    // SEA assets provider (read-only)

Disclaimer: I've used a significant amount of Claude Code tokens to create this PR. I've reviewed all changes myself.


Fixes #60021

@nodejs-github-bot
Copy link
Collaborator

Review requested:

  • @nodejs/single-executable
  • @nodejs/test_runner

@nodejs-github-bot nodejs-github-bot added lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run. labels Jan 22, 2026
@avivkeller avivkeller added fs Issues and PRs related to the fs subsystem / file system. module Issues and PRs related to the module subsystem. semver-minor PRs that contain new features and should be released in the next minor version. notable-change PRs with changes that should be highlighted in changelogs. needs-benchmark-ci PR that need a benchmark CI run. test_runner Issues and PRs related to the test runner subsystem. labels Jan 22, 2026
@github-actions
Copy link
Contributor

The notable-change PRs with changes that should be highlighted in changelogs. label has been added by @avivkeller.

Please suggest a text for the release notes if you'd like to include a more detailed summary, then proceed to update the PR description with the text or a link to the notable change suggested text comment. Otherwise, the commit will be placed in the Other Notable Changes section.

@Ethan-Arrowood
Copy link
Contributor

Nice! This is a great addition. Since it's such a large PR, this will take me some time to review. Will try to tackle it over the next week.

*/
existsSync(path) {
// Prepend prefix to path for VFS lookup
const fullPath = this.#prefix + (StringPrototypeStartsWith(path, '/') ? path : '/' + path);
Copy link
Member

Choose a reason for hiding this comment

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

Can we use path.join?

validateObject(files, 'options.files');
}

const { VirtualFileSystem } = require('internal/vfs/virtual_fs');
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't we import this at the top level / lazy load it at the top level?

ArrayPrototypePush(this.#mocks, {
__proto__: null,
ctx,
restore: restoreFS,
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
restore: restoreFS,
restore: ctx.restore,

nit

* @param {object} [options] Optional configuration
*/
addFile(name, content, options) {
const path = this._directory.path + '/' + name;
Copy link
Member

Choose a reason for hiding this comment

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

Can we use path.join?

let entry = current.getEntry(segment);
if (!entry) {
// Auto-create parent directory
const dirPath = '/' + segments.slice(0, i + 1).join('/');
Copy link
Member

Choose a reason for hiding this comment

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

Let's use path.join

let entry = current.getEntry(segment);
if (!entry) {
// Auto-create parent directory
const parentPath = '/' + segments.slice(0, i + 1).join('/');
Copy link
Member

Choose a reason for hiding this comment

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

path.join?

}
}
callback(null, content);
}).catch((err) => {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
}).catch((err) => {
}, (err) => {

Comment on lines +676 to +677
const bytesToRead = Math.min(length, available);
content.copy(buffer, offset, readPos, readPos + bytesToRead);
Copy link
Member

Choose a reason for hiding this comment

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

Primordials?

}

callback(null, bytesToRead, buffer);
}).catch((err) => {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
}).catch((err) => {
}, (err) => {

@avivkeller
Copy link
Member

Left an initial review, but like @Ethan-Arrowood said, it'll take time for a more in depth look

@joyeecheung
Copy link
Member

joyeecheung commented Jan 22, 2026

It's nice to see some momentum in this area, though from a first glance it seems the design has largely overlooked the feedback from real world use cases collected 4 years ago: https://github.com/nodejs/single-executable/blob/main/docs/virtual-file-system-requirements.md - I think it's worth checking that the API satisfies the constraints that users of this feature have provided, to not waste the work that have been done by prior contributors to gather them, or having to reinvent it later (possibly in a breaking manner) to satisfy these requirements from real world use cases.

@codecov
Copy link

codecov bot commented Jan 22, 2026

Codecov Report

❌ Patch coverage is 89.32170% with 710 lines in your changes missing coverage. Please review.
✅ Project coverage is 89.65%. Comparing base (48c208f) to head (0abdb2f).
⚠️ Report is 56 commits behind head on main.

Files with missing lines Patch % Lines
lib/internal/vfs/module_hooks.js 83.89% 204 Missing and 1 partial ⚠️
lib/internal/vfs/providers/sea.js 63.26% 161 Missing and 1 partial ⚠️
lib/internal/vfs/providers/memory.js 86.64% 101 Missing and 2 partials ⚠️
lib/internal/vfs/providers/real.js 85.26% 56 Missing ⚠️
lib/internal/vfs/provider.js 92.40% 37 Missing and 4 partials ⚠️
lib/internal/vfs/watcher.js 92.83% 35 Missing and 3 partials ⚠️
lib/internal/vfs/file_system.js 97.34% 27 Missing ⚠️
lib/internal/vfs/streams.js 88.05% 19 Missing ⚠️
lib/internal/vfs/sea.js 84.04% 15 Missing ⚠️
lib/internal/vfs/file_handle.js 97.42% 12 Missing and 2 partials ⚠️
... and 7 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #61478      +/-   ##
==========================================
- Coverage   91.64%   89.65%   -2.00%     
==========================================
  Files         337      691     +354     
  Lines      140455   213208   +72753     
  Branches    21779    40576   +18797     
==========================================
+ Hits       128716   191144   +62428     
- Misses      11517    14175    +2658     
- Partials      222     7889    +7667     
Files with missing lines Coverage Δ
lib/internal/bootstrap/realm.js 96.21% <100.00%> (+0.85%) ⬆️
lib/internal/modules/cjs/loader.js 98.14% <100.00%> (+18.56%) ⬆️
lib/internal/modules/esm/load.js 91.47% <100.00%> (+8.07%) ⬆️
lib/internal/modules/esm/resolve.js 99.03% <100.00%> (+11.18%) ⬆️
lib/internal/modules/esm/translators.js 97.65% <100.00%> (+6.24%) ⬆️
lib/internal/modules/package_json_reader.js 99.72% <100.00%> (+12.12%) ⬆️
lib/internal/vfs/errors.js 100.00% <100.00%> (ø)
lib/internal/vfs/router.js 100.00% <100.00%> (ø)
lib/vfs.js 100.00% <100.00%> (ø)
src/node_builtins.cc 76.38% <100.00%> (ø)
... and 18 more

... and 452 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@jimmywarting
Copy link

jimmywarting commented Jan 22, 2026

And why not something like OPFS aka whatwg/fs?

const rootHandle = await navigator.storage.getDirectory()
await rootHandle.getFileHandle('config.json', { create: true })
fs.mount('/app', rootHandle) // to make it work with fs
fs.readFileSync('/app/config.json')

OR

const rootHandle = await navigator.storage.getDirectory()
await rootHandle.getFileHandle('config.json', { create: true })

fs.readFileSync('sandbox:/config.json')

fs.createVirtual seems like something like a competing specification

@mcollina mcollina force-pushed the vfs branch 3 times, most recently from 5e317de to 977cc3d Compare January 23, 2026 08:15
@mcollina
Copy link
Member Author

And why not something like OPFS aka whatwg/fs?

I generally prefer not to interleave with WHATWG specs as much as possible for core functionality (e.g., SEA). In my experience, they tend to perform poorly on our codebase and remove a few degrees of flexibility. (I also don't find much fun in working on them, and I'm way less interested in contributing to that.)

On an implementation side, the core functionality of this feature will be identical (technically, it's missing writes that OPFS supports), as we would need to impact all our internal fs methods anyway.

If this lands, we can certainly iterate on a WHATWG-compatible API for this, but I would not add this to this PR.

@juliangruber
Copy link
Member

Small prior art: https://github.com/juliangruber/subfs

@mcollina mcollina force-pushed the vfs branch 2 times, most recently from 8d711c1 to 73c18cd Compare January 23, 2026 13:19
@Qard
Copy link
Member

Qard commented Jan 23, 2026

I also worked on this a bit on the side recently: Qard@73b8fc6

That is very much in chaotic ideation stage with a bunch of LLM assistance to try some different ideas, but the broader concept I was aiming for was to have a VirtualFileSystem type which would actually implement the entire API surface of the fs module, accepting a Provider type to delegate the internals of the whole cluster of file system types to a singular class managing the entire cluster of fs-related types such that the fs module could actually just be fully converted to:

module.exports = new VirtualFileSystem(new LocalProvider())

I intended for it to be extensible for a bunch of different interesting scenarios, so there's also an S3 provider and a zip file provider there, mainly just to validate that the model can be applied to other varieties of storage systems effectively.

Keep in mind, like I said, the current state is very much just ideation in a branch I pushed up just now to share, but I think there are concepts for extensibility in there that we could consider to enable a whole ecosystem of flexible storage providers. 🙂

Personally, I would hope for something which could provide both read and write access through an abstraction with swappable backends of some variety, this way we could pass around these virtualized file systems like objects and let an ecosystem grow around accepting any generalized virtual file system for its storage backing. I think it'd be very nice for a lot of use cases like file uploads or archive management to be able to just treat them like any other readable and writable file system.

@jimmywarting
Copy link

jimmywarting commented Jan 23, 2026

Personally, I would hope for something which could provide both read and write access through an abstraction with swappable backends of some variety, this way we could pass around these virtualized file systems like objects and let an ecosystem grow around accepting any generalized virtual file system for its storage backing. I think it'd be very nice for a lot of use cases like file uploads or archive management to be able to just treat them like any other readable and writable file system.

just a bit off topic... but this reminds me of why i created this feature request:
Blob.from() for creating virtual Blobs with custom backing storage

Would not lie, it would be cool if NodeJS also provided some type of static Blob.from function to create virtual lazy blobs. could live on fs.blobFrom for now...

example that would only work in NodeJS (based on how it works internally)

const size = 26

const blobPart = BlobFrom({
  size,
  stream (start, end) {
    // can either be sync or async (that resolves to a ReadableStream)
    // return new Response('abcdefghijklmnopqrstuvwxyz'.slice(start, end)).body
    // return new Blob(['abcdefghijklmnopqrstuvwxyz'.slice(start, end)]).stream()
    
    return fetch('https://httpbin.dev/range/' + size, {
      headers: {
        range: `bytes=${start}-${end - 1}`
      }
    }).then(r => r.body)
  }
})

blobPart.text().then(text => {
  console.log('a-z', text)
})

blobPart.slice(-3).text().then(text => {
  console.log('x-z', text)
})

const a = blobPart.slice(0, 6)
a.text().then(text => {
  console.log('a-f', text)
})

const b = a.slice(2, 4)
b.text().then(text => {
  console.log('c-d', text)
})
x-z xyz
a-z abcdefghijklmnopqrstuvwxyz
a-f abcdef
c-d cd

An actual working PoC

(I would not rely on this unless it became officially supported by nodejs core - this is a hack)

const blob = new Blob()
const symbols = Object.getOwnPropertySymbols(blob)
const blobSymbol = symbols.map(s => [s.description, s])
const symbolMap = Object.fromEntries(blobSymbol)
const {
  kHandle,
  kLength,
} = symbolMap

function BlobFrom ({ size, stream }) {
  const blob = new Blob()
  if (size === 0) return blob

  blob[kLength] = size
  blob[kHandle] = {
    span: [0, size],

    getReader () {
      const [start, end] = this.span
      if (start === end) {
        return { pull: cb => cb(0) }
      }

      let reader

      return {
        async pull (cb) {
          reader ??= (await stream(start, end)).getReader()
          const {done, value} = await reader.read()
          cb(done ^ 1, value)
        }
      }
    },

    slice (start, end) {
      const [baseStart] = this.span

      return {
        span: [baseStart + start, baseStart + end],
        getReader: this.getReader,
        slice: this.slice,
      }
    }
  }

  return blob
}

currently problematic to do: new Blob([a, b]), new File([blobPart], 'alphabet.txt', { type: 'text/plain' })

also need to handle properly clone, serialize & deserialize, if this where to be sent of to another worker - then i would transfer a MessageChannel where the worker thread asks main frame to hand back a transferable ReadableStream when it needs to read something.

but there are probably better ways to handle this internally in core with piping data directly to and from different destinations without having to touch the js runtime? - if only getReader could return the reader directly instead of needing to read from the ReadableStream using js?

Add loaderStat(), loaderReadFile(), and setLoaderFsOverrides() to
helpers.js, and modify toRealPath() to support a VFS toggle. Replace
direct internalFsBinding.internalModuleStat() and fs.readFileSync()
calls in the CJS loader, ESM resolver, ESM loader, translators, and
package_json_reader with these wrappers.

The VFS module_hooks.js now calls setLoaderFsOverrides() first in
installHooks(), making loader fs interception order-independent and
eliminating conflicts with cached fs method references.

Fix two pre-existing bugs in esm/resolve.js finalizeResolution():
- StringPrototypeEndsWith() was called with internalFsBinding as
  first arg instead of path
- StringPrototypeSlice(path, -1) returned the last char instead of
  stripping the trailing slash (now correctly uses path, 0, -1)

Existing fs patches for user-facing operations are kept unchanged.
@mcollina
Copy link
Member Author

mcollina commented Mar 5, 2026

@joyeecheung I added back the toggles for loading modules. PTAL.

@mcollina
Copy link
Member Author

mcollina commented Mar 5, 2026

@avivkeller PTAL

@nodejs-github-bot
Copy link
Collaborator

mcollina and others added 3 commits March 7, 2026 07:55
- Remove redundant #getBaseName/#getParentPath from MemoryProvider,
  use pathPosix.basename/dirname directly
- Remove redundant getBaseName/getParentPath/splitPath from router.js,
  keep only functions with non-trivial VFS-specific logic
- Convert RealFSProvider constant getters (readonly, supportsSymlinks)
  to readonly properties via ObjectDefineProperty
- Fix joinVFSPath/normalizeVFSPath to detect Windows drive-letter paths
  by checking for ':' at position 1 instead of checking for leading '/',
  so bare '/' is always treated as a POSIX VFS path
- Update test-vfs-internals.js to match router.js export changes
Use path.resolve() instead of pathPosix.normalize() for VFS path
normalization so mount points resolve correctly on Windows (e.g.
/virtual -> C:\virtual). Use path.sep and path.relative() in router
for cross-platform mount point matching. Remove normalizeVFSPath and
joinVFSPath wrappers in favor of direct path utility calls. Update
tests to use path.resolve()/path.normalize() for platform-portable
assertions.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Remove blank lines between JSDoc description and @param tags
(jsdoc/tag-lines) and remove unused `common` variable assignment
(no-unused-vars).
@TheOneTheOnlyJJ
Copy link
Contributor

@codebytere

I'm not sure if you're the right person to tag, but this may be of interest to the Electron team and worth some feedback on for potential Electron use cases. Off the top of my head for example, it may be a potential replacement for electron/asar or have some other relevant use cases?

Copy link
Contributor

@ShogunPanda ShogunPanda left a comment

Choose a reason for hiding this comment

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

LGTM!

@nodejs-github-bot
Copy link
Collaborator

@nodejs-github-bot
Copy link
Collaborator

@joyeecheung
Copy link
Member

Off the top of my head for example, it may be a potential replacement for electron/asar or have some other relevant use cases

I think one thing that this cannot replace asar for is the ability to pack/unpack an archive based on what's in the VFS, which is useful especially in reproducibility. But the current design doesn't seem to be in conflict with implementing that later in a follow up.

@@ -27,7 +27,7 @@ const { kEmptyObject } = require('internal/util');
const modulesBinding = internalBinding('modules');
Copy link
Member

@joyeecheung joyeecheung Mar 10, 2026

Choose a reason for hiding this comment

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

modulesBinding methods used below should still reroute to VFS, they are currently reading into the real FS via c++. Not patching them means syntax detection and error decoration that are re-loading the package.json are going to read into real FS for non-existent/different files and see mismatches - they can probably use some tests too.

Copy link
Member

@Qard Qard left a comment

Choose a reason for hiding this comment

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

Mostly LGTM, but I worry the vfs-mount event on process may be insufficient as a security control. I think we'll probably want a proper permission system control for that which can't be tampered with.

doc/api/vfs.md Outdated
* Only specific targeted files are affected.
* Other operations appear to work normally.

### Monitoring VFS mounts
Copy link
Member

Choose a reason for hiding this comment

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

Seems handy, but is there a reason for going for this rather than a stricter permission system block? Could also do both, but I think lots of users would want to be able to just hard-crash with a permission error if anything tries to mount unexpectedly. Process event handlers can be tampered with to remove the listener, so this alone is not so much of a security measure. 🤔

Copy link
Member Author

Choose a reason for hiding this comment

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

I'll remove this

Wrap modulesBinding.readPackageJSON(), getNearestParentPackageJSON(),
getPackageScopeConfig(), and getPackageType() with toggleable overrides
so that VFS-mounted package.json files are read from virtual storage
instead of the real filesystem. This fixes syntax detection and error
decoration that re-read package.json bypassing VFS.

The implementation follows the existing loaderStat/loaderReadFile toggle
pattern in helpers.js.
Remove the vfs-mount/vfs-unmount events emitted on process, as they
are insufficient as a security control and a proper permission system
is needed instead.
Add tests covering require() of ESM modules from VFS with package.json
type detection (.js with type:module, nested directory walk-up, ESM-to-ESM
imports) and .mjs extension-based ESM loading without type:module.
Copy link
Contributor

@ShogunPanda ShogunPanda left a comment

Choose a reason for hiding this comment

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

LGTM!

@nodejs-github-bot
Copy link
Collaborator

bool use_vfs;
if (field.value().get_bool().get(use_vfs)) {
FPrintF(
stderr, "\"useVfs\" field of %s is not a Boolean\n", config_path);
Copy link
Member

Choose a reason for hiding this comment

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

Can you add validation below to make sure that it errors when useVfs is enabled together with useCodeCache/useSnapshot/mainFormat: "module"?


/**
* Install fs patches for user code transparency.
* These make fs.readFileSync('/vfs/path'), fs.statSync, etc. work for user code.
Copy link
Member

@joyeecheung joyeecheung Mar 12, 2026

Choose a reason for hiding this comment

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

This function seems misplaced - they don't have much to do with module loading. It's also strange that for a VFS overlay implementation, lib/fs is not touched in this PR - I think what this tries to do belongs there instead. Since we have access to the true fs originals, it would be much more robust if in lib/fs we just wrap the fs methods and reroute to vfs when toggled - I don't imagine that'll be very expensive since when it's not enabled, it's just one extra boolean check, we can modify the exports in fs.js to add a layer of:

function readFileSync(...) {
  if (vfsEnabled) return maybeVfs(...);
  return originalFeadFileSync(...);
}

And let the vfsEnabled be toggle-able in vfs.mount(). Otherwise this patching would not work if some other code cache access to fs first i.e. something like #62012, then after vfs.mount(), they would not see the effect.:

// 1. Some library code gets loaded and cache fs methods first
const { readFileSync } = require('fs');
function foo(path) {
   readFileSync(path);
}

// 2. Some other code does the vfs mounting
vfs.mount();

// 3. User tries to use foo
foo('/vfs/path');  // This won't see the vfs overlay

If we wrap what gets exported in fs.js completely, however, even if any other code cache access to fs methods before the call to vfs.mount(), they will always see vfs interception once enabled. I think that will be the most important characteristics of a built-in vfs overlay implementation - rerouting fs methods regardless of loading order is something only Node.js core can safely do, if we don't do the wrapping and only do a hacky patch like user land solutions, then this isn't much better than a brittle user land solution.

* @param {string} basePath The base path without extension
* @returns {string|null} The resolved path with extension, or null
*/
function tryExtensions(vfs, basePath) {
Copy link
Member

@joyeecheung joyeecheung Mar 12, 2026

Choose a reason for hiding this comment

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

This and the code below does not look right - we are re-inventing a different version of module resolution with random quirks, and this will become a maintenance burden. Take tryExtensions here for example: the true tryExtensions in cjs/loader would also consider --preserve-symlinks-main and --preserve-symlinks, this version, however, doesn't , even if vfs support symlinks, so the resolution algorithm becomes different within the vfs than in a real fs. The list of extensions also get hard-coded here instead of being in sync with Object.keys(Module._extensions), which is what the true module resolution uses. We could've just redirect the stat call with a wrapper in the tryExtensions in cjs/loader to consult the vfs if necessary, similar to what other helpers do, and all the rest of the logic will remain in one place, instead of being duplicated here with footguns in the subtle differences.

The same applies to many other methods in this file e.g. the re-invented resolveConditions doesn't handle error recovery correctly, resolvePackageExports doesn't support patterns, resolveBareSpecifier has an odd choice of delegating to nextResolve for #imports, etc. Unless we want to document all these quirks, it's better to just update the canonical implementation to reroute to VFS if necessary, and reuse them.

Add SEA config validation to error when useVfs is enabled together with
useSnapshot, useCodeCache, or mainFormat: "module", as these combinations
are not supported.
@mcollina
Copy link
Member Author

@joyeecheung can we land this and iterate? This is starting to get immense.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fs Issues and PRs related to the fs subsystem / file system. lib / src Issues and PRs related to general changes in the lib or src directory. module Issues and PRs related to the module subsystem. needs-benchmark-ci PR that need a benchmark CI run. needs-ci PRs that need a full CI run. notable-change PRs with changes that should be highlighted in changelogs. semver-minor PRs that contain new features and should be released in the next minor version. test_runner Issues and PRs related to the test runner subsystem. tsc-agenda Issues and PRs to discuss during the meetings of the TSC.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement VFS (Virtual File System) Hooks for Single Executable Applications