Skip to content

sea: mount bundled assets as a virtual file system - #65675

Draft
mcollina wants to merge 2 commits into
nodejs:mainfrom
mcollina:vfs-sea-integration
Draft

sea: mount bundled assets as a virtual file system#65675
mcollina wants to merge 2 commits into
nodejs:mainfrom
mcollina:vfs-sea-integration

Conversation

@mcollina

@mcollina mcollina commented Aug 31, 2026

Copy link
Copy Markdown
Member

This adds the SEA integration for the virtual file system landed in #63653: setting "useVfs": true in the SEA configuration mounts the bundled assets as a read-only VFS and runs the injected main script from inside the mount.

Since a VFS never shadows the real file system and its mount point is reserved and chosen at runtime, there is no fixed /sea path. Instead, the main script is placed at the root of the mount and executed from there, so:

  • __filename and __dirname point inside the virtual file system;
  • assets are reached through __dirname-relative paths with regular node:fs APIs;
  • relative require() calls and node_modules lookups resolve against the bundled assets, confined to the mount by the module loader integration.

Implementation notes:

  • The main script is not duplicated into the assets at build time; its source already lives in the SEA blob and is injected into the provider at runtime.
  • SEAProvider is read-only and lazy: asset content stays in the executable's SEA blob and is copied into JS memory only when a file is opened, with sizes cached for stat.
  • The implicit SEA mount does not emit the VirtualFileSystem experimental warning; the SEA warning already covers it.
  • ESM entry points ("mainFormat": "module") are supported: the ESM main is loaded from inside the mount through the ESM loader, so import.meta.url/filename/dirname reflect the mount and static imports, dynamic import(), and bare specifier lookups resolve against the bundled assets.
  • "useVfs" is rejected together with "useSnapshot" and "useCodeCache".

This PR was prepared with the help of AI. I've reviewed all changes myself.

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Review requested:

  • @nodejs/single-executable

@nodejs-github-bot nodejs-github-bot added lib / src Issues and PRs involving general changes in the lib/ or src/ directories. needs-ci PRs that need a full CI run. labels Aug 31, 2026
@mcollina
mcollina force-pushed the vfs-sea-integration branch 2 times, most recently from 7e3ed4b to 148a0d7 Compare August 31, 2026 09:13
Add a "useVfs" boolean to the SEA configuration. When enabled, the
bundled assets are mounted as a read-only virtual file system before
the main script runs, and the main script is placed at the mount point
root and executed from there via wrapModuleLoad. __filename, __dirname,
relative require() calls, and node_modules lookups then all resolve
against the bundled assets, confined to the mount. Since a VFS never
shadows the real file system, bundled code reaches the assets through
__dirname-relative paths instead of a fixed mount location.

The new SEAProvider derives the directory tree from the asset keys and
keeps asset content in the executable's SEA blob, copying it into JS
memory only when a file is opened. The main script is not duplicated
into the assets at build time; its source already lives in the blob and
is injected into the provider at runtime. The implicit SEA mount does
not emit the VirtualFileSystem experimental warning, which is already
covered by the SEA warning.

"useVfs" is rejected together with "useSnapshot", "useCodeCache",
and "mainFormat": "module"; ESM entry points are left as future
work.

Signed-off-by: Matteo Collina <hello@matteocollina.com>
@mcollina
mcollina force-pushed the vfs-sea-integration branch from 148a0d7 to 4991e64 Compare August 31, 2026 09:14
Allow "mainFormat": "module" together with "useVfs": true. The
ESM main script is placed at the mount point root like the CommonJS
one, and loaded through the ESM loader via runEntryPointWithESMLoader,
so import.meta.url, import.meta.filename, and import.meta.dirname
reflect the location of the main module inside the virtual file
system, and static imports, dynamic import(), and bare specifier
lookups all resolve against the bundled assets.

Signed-off-by: Matteo Collina <hello@matteocollina.com>
@mcollina
mcollina requested review from Qard and joyeecheung and removed request for Qard August 31, 2026 10:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lib / src Issues and PRs involving general changes in the lib/ or src/ directories. needs-ci PRs that need a full CI run.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants