Node.js Gains Native Virtual File System – How Claude Code Made It Possible

Node.js introduces a built‑in virtual file system via the upcoming node:vfs module and the @platformatic/vfs package, addressing long‑standing limitations in module import and file sandboxing, with detailed usage examples, mounting modes, full fs API support, and discussion of why core integration is essential.

Node.js Tech Stack
Node.js Tech Stack
Node.js Tech Stack
Node.js Gains Native Virtual File System – How Claude Code Made It Possible

Pain points: why existing solutions fall short

Community packages such as memfs, unionfs and mock-fs attempt to provide an in‑memory file system, but they can only patch the fs module and cannot intervene in the module resolver.

This means that while they can intercept fs.readFileSync(), they cannot handle imports like import('./config.json') or require('./utils'); those requests bypass the virtual layer and hit the real file system.

Four concrete scenarios illustrate the need for a true virtual file system:

Single‑file executable packaging : bundling configuration files, templates and static assets requires a consistent path for fs.readFileSync(), otherwise files are duplicated or require glue code.

Test isolation : each test case should have an isolated file system without leaving traces on disk. memfs can mock fs, but the mocked files cannot be loaded via import or require().

Multi‑tenant sandboxing : tenants must be confined to a specific directory, preventing path traversal (e.g., ../). Currently this requires fragile custom validation.

AI‑generated code execution : generated JavaScript is often written to a temporary file before loading, which is slow, insecure and leaves cleanup problems.

What node:vfs looks like

Basic usage creates a VFS instance, writes a module, mounts it, and reads it via the standard fs API:

import vfs from 'node:vfs'
import fs from 'node:fs'

const myVfs = vfs.create()
myVfs.mkdirSync('/app')
myVfs.writeFileSync('/app/module.mjs', 'export default "hello from VFS"')
myVfs.mount('/virtual')

// Standard fs can read the virtual file
const data = fs.readFileSync('/virtual/app/module.mjs', 'utf8')

// Import also works
const mod = await import('/virtual/app/module.mjs')
console.log(mod.default) // "hello from VFS"

myVfs.unmount()

After myVfs.mount('/virtual'), the VFS is truly mounted on both the fs module and the module resolver, so any code reading /virtual paths receives data from the VFS. Third‑party libraries need no adaptation; for example, express.static('/virtual/public') works out of the box.

Mount modes

Mount mode : the VFS is active only under a specified path prefix, completely isolated from the real file system. Suitable for scenarios that require a clean, independent space.

Overlay mode : the VFS overlays the real file system, checking virtual paths first and falling back to the real file system when a path is missing. This is handy for tests where only a few configuration files need to be overridden.

const myVfs = vfs.create({ overlay: true })
myVfs.writeFileSync('/etc/config.json', '{"mocked": true}')
myVfs.mount('/')
// /etc/config.json comes from VFS
// /etc/hostname comes from the real file system

Full fs API support

The VFS is not a subset of fs; it implements the complete synchronous, callback and Promise APIs, covering reads, writes, directory operations, symlinks, file descriptors, streams, file watching and glob matching. Error codes such as ENOENT, ENOTDIR, EISDIR, EEXIST are preserved.

Why it must be in core

Although the user‑space package @platformatic/vfs works today, integrating the feature into Node.js core solves five fundamental problems:

Duplicate module‑resolution logic : the user‑space package re‑implements about 960 lines of logic that already exists in Node.js (traversing node_modules, handling

package.json
exports

, conditional exports, etc.).

Reliance on private APIs : it patches Module._resolveFilename and Module._extensions, which can break with any minor Node.js version bump.

Fragile global fs patching : if code caches references to fs.readFileSync before the VFS mounts, those references bypass the VFS. Core integration intercepts calls below the public API, catching cached references.

Native module loading : loading compiled addons via dlopen() requires a real file path; user‑space cannot provide in‑memory .node files, whereas core integration can.

Module‑cache cleanup : after unmounting, modules loaded via require() remain in require.cache. The core VFS can track origins and automatically clean up.

Use it now: @platformatic/vfs

If you don’t want to wait for the core PR, install the user‑space package (supports Node.js 22+): npm install @platformatic/vfs The API mirrors the proposed node:vfs API, so migration will be a single import change:

// Today
import { create } from '@platformatic/vfs'
// Future
import { create } from 'node:vfs'

Vercel’s CTO Malte Ubl independently created a polyfill ( node-vfs-polyfill) after seeing Matteo’s PR, confirming the design’s soundness.

Additional storage providers

The user‑space package also offers providers not present in the core PR:

SqliteProvider : a persistent VFS backed by node:sqlite. Files survive process restarts, useful for caching compiled artifacts.

import { create, SqliteProvider } from '@platformatic/vfs'

const disk = new SqliteProvider('/tmp/myfs.db')
const vfs = create(disk)
vfs.writeFileSync('/config.json', '{"saved": true}')
disk.close()

// In another process
const disk2 = new SqliteProvider('/tmp/myfs.db')
const vfs2 = create(disk2)
console.log(vfs2.readFileSync('/config.json', 'utf8')) // '{"saved": true}'

RealFSProvider : a sandboxed real‑file‑system access layer with built‑in path‑traversal protection (uses path.resolve()).

import { create, RealFSProvider } from '@platformatic/vfs'

const provider = new RealFSProvider('/tmp/sandbox')
const vfs = create(provider)
vfs.writeFileSync('/file.txt', 'sandboxed') // writes to /tmp/sandbox/file.txt
vfs.readFileSync('/../../../etc/passwd') // throws – cannot escape

The story behind the 14 000‑line PR

Matteo Collina disclosed that the PR contains roughly 14 000 lines across 66 files. He completed the work over the 2025 Christmas break, leveraging Claude Code to generate the repetitive parts: synchronous, callback and Promise variants of every fs method, test coverage and documentation. He focused on architecture, API design and line‑by‑line review.

He said, "Without AI this could not have been a holiday side‑project; it simply would not have happened." The PR is now under active review. Joyee Cheung (Igalia) performed a strict security model audit, while James Snell and Paolo Insogna approved the changes. Stephen Belanger raised concerns about global mount() hijacking and suggested integration with the permission model.

Personal observations

Node.js has long had mature I/O abstractions, but a virtual file system has been a missing piece. The SEA packaging, test isolation and AI‑code‑execution scenarios are genuine pain points, not just hype.

The feature is still experimental and touches many parts of the fs module, so edge cases and compatibility issues are expected.

If you have the mentioned needs, you can try @platformatic/vfs today; once node:vfs lands in core, migration will be as easy as changing a single import.

Related links:

node:vfs PR: https://github.com/nodejs/node/pull/61478

@platformatic/vfs: https://github.com/platformatic/vfs

Vercel polyfill: https://github.com/vercel-labs/node-vfs-polyfill

Blog post: https://blog.platformatic.dev/why-nodejs-needs-a-virtual-file-system

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

AI code generationNode.jsmodule loaderVirtual File Systemnode:vfs@platformatic/vfs
Node.js Tech Stack
Written by

Node.js Tech Stack

Focused on sharing AI, programming, and overseas expansion

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.