Filesystem
The virtual filesystem — an in-memory tree with pluggable providers, blob-backed large files, persistence, and tar.gz snapshots.
Every box has a VFS — a virtual filesystem that behaves like a POSIX tree
(files, directories, symlinks, permissions, mtimes) but lives in memory as plain
JavaScript objects. It's the single source of truth that the shell, commands,
and the Node fs shim all read and write.
The tree and its API
The VFS exposes the operations you'd expect, synchronously at the core level:
kernel.vfs.writeFile("/home/user/a.txt", "hello");
kernel.vfs.readFileString("/home/user/a.txt"); // "hello"
kernel.vfs.readdir("/home/user"); // Dirent[]
kernel.vfs.stat("/home/user/a.txt"); // Stat
kernel.vfs.mkdir("/tmp/x", { recursive: true });The Sandbox fs helper wraps these in a promise-based,
node:fs-shaped API (readFile, writeFile, readdir, stat, mkdir, rm,
exists, rename, cp), and the Node runtime maps
node:fs / node:fs/promises onto the same tree.
The VFS also emits watch events (vfs.watch(listener)), which power fs.watch
in the Node layer, HMR file watching for dev servers, and the kernel's own
save-on-change persistence.
Providers: synthetic and mounted paths
Not every path is a plain in-memory file. The VFS supports providers mounted at a path prefix:
/proc— synthetic process/system info generated on read./dev— device-like files.NativeFsProvider— backs a subtree with a real host directory. In Node, themountsoption uses this so a box reads and writes files on your machine; it can also take a customNativeFsModule.
Large files: blob & content store
Small files live inline in the tree. Large or binary files are chunked and
stored in a content store backed by a blob store — MemoryBlobStore by
default, or IndexedDBBlobStore in the browser. Content is addressed by hash
(hashBytes), so identical data is stored once. CHUNK_THRESHOLD and
CHUNK_SIZE control when and how a file is chunked.
Persistence
The kernel drives persistence through a PersistenceManager and a pluggable
PersistenceBackend:
IndexedDBPersistenceBackend— the browser default; the VFS is serialized and saved to IndexedDB, debounced on change, so a box survives a reload.MemoryPersistenceBackend— volatile; nothing is written out.
Serialization is exposed directly too (serialize / deserialize,
SerializedNode) if you want to manage box images yourself.
Snapshots
Beyond incremental persistence, a box's whole disk can be exported as a
tar.gz and restored elsewhere — the basis for saving, cloning, and moving boxes
between environments.
const image = await sandbox.fs.exportSnapshot(); // Uint8Array (tar.gz)
await otherSandbox.fs.importSnapshot(image);Note
Snapshots are whole-disk, point-in-time images. A write-ahead log for crash-consistent, incremental durability is on the roadmap, alongside choosing the backing store per environment (IndexedDB/OPFS in the browser, the host filesystem via the CLI, or purely volatile).