Warning
Alpha. Mountx is early development: the API can still change, and it has not been through a security or correctness audit. A driver is reachable by every program on the machine once it is mounted.
Write a filesystem in JavaScript, mount it as a real kernel filesystem.
You can write a driver with the same methods as node:fs/promises (stat,
readdir, open, mkdir, rename). Mountx takes your driver and turns it into a real folder on the machine, so ls, cat, AI Agents, VSCode and any other program can use it.
There is no special API to learn: node:fs/promises already is the
interface, and the errors it throws already are the error format.
So anything that behaves a bit like a filesystem can get a real path: an in-memory store, a zip file, an S3 bucket, a database, or a plain folder served back out with your own rules on top.
import { mount } from "mountx/auto";
import { createLoopback } from "mountx";
import { createMemoryDriver } from "mountx/drivers/memory";
// A driver is any object with stat(), readdir(), open(), [mkdir()] and [rename()] methods.
// Mountx has built-in memory, fs and unstorage drivers
const driver = createMemoryDriver();
// Work with FS in-process without mounting
const fs = createLoopback(driver);
await fs.mkdir("/notes");
await fs.writeFile("/notes/hello.txt", "hi!");
new TextDecoder().decode(await fs.readFile("/notes/hello.txt")); // "hi"
// Mount the driver to the kernel with whatever this host can use
// FUSE on Linux (no root needed), NFSv3 on macOS
await using mounted = await mount(driver, "/mnt/point", {
fuse: { attrTimeout: 10 }, // seconds the kernel may cache attributes
});
/**
# /mnt/point is a real folder now, so every program on the machine can use it:
$ cat /mnt/point/notes/hello.txt => hi!
$ echo hey > /mnt/point/notes/other.txt
**/
if (mounted.transport === "fuse") {
mounted.notifyInvalInode(2n); // storage changed behind mountx's back? drop the cache
}
await mounted.unmount(); // or let `await using` do it at the end of the blocknpx nypm i mountxOr mount a demo filesystem right now, and watch every request the kernel makes:
npx mountx- Quick Start — install it and have a folder in about a minute.
- Drivers — the three built-in ones, and the interface for writing your own.
- Mounting —
mount(), the mount object, lifecycle and unmount. - Tuning — caching, concurrency, and the measured numbers.
- Troubleshooting — the things that will bite you, and how to recover.
- Transports — FUSE and NFSv3, what each costs, and how to pin one.
- Reference — every entry point, option and type.
local development
- Clone this repository
- Install the latest LTS version of Node.js
- Enable Corepack with
corepack enable - Install dependencies with
pnpm install - Run tests in watch mode with
pnpm dev pnpm mountxruns the CLI (src/cli/index.ts) from source: it mounts an in-memory copy of this README at~/mountxand logs every driver call it servespnpm testruns lint, typecheck and the suites that need no root;pnpm test:rootlessadds the unprivileged real-mount suite (still nosudo);pnpm test:rootadds the ones that do need it.pnpm build:nativerebuilds the FUSE mount helper withzig buildand re-embeds it intonative/prebuilt.mjs, which is the committed artifact — the.nodefiles it is built from are gitignored. Only needed whennative/src/changes.pnpm matrixandpnpm bench/pnpm bench:rootregenerate the two committed reports the docs draw from (.agents/conformance-matrix.md,.agents/benchmarks.md).- The docs site is
docs/, its own pnpm project:cd docs && pnpm install && pnpm dev.
Published under the MIT license 💛.