mountx
Write a filesystem in JavaScript, mount it as a real folder.

Write an object with the same methods as `node:fs/promises` and mountx turns it into a real folder on the machine — so `ls`, `cat`, your editor and every other program can use it. There is no special API to learn: `node:fs/promises` already is the interface.
import { mount } from "mountx/auto";
import { createMemoryDriver } from "mountx/drivers/memory";

// A driver is any object with stat(), readdir() and open().
const driver = createMemoryDriver();

// FUSE (no root needed) then 9P on Linux, NFSv3 on macOS.
await using mounted = await mount(driver, "/mnt/point");

mounted.transport; // "fuse" | "9p" | "nfs"

// $ echo hi > /mnt/point/hello.txt
// $ cat /mnt/point/hello.txt

Features

No API to learn

A driver is a subset of node:fs/promisesstat, readdir, open. Node's own fs/promises is a valid driver, unchanged.

A real folder

Every program on the machine sees an ordinary path. Shell tools, editors, build systems and agents need to know nothing about it.

One API, three transports

FUSE where FUSE works, then 9P, then NFS everywhere else. mountx/auto probes the host, picks one, and hands back that transport's own mount object.

No root on Linux

Unprivileged mounting through fusermount3, the setuid helper FUSE already ships. Serving never needs privileges on any transport.

Pure JavaScript

Zero runtime dependencies, all three protocols implemented from the specs. The one native piece is a ~7 KB helper that only unprivileged FUSE mounts load.

Develop without mounting

createLoopback(driver) runs your driver like fs/promises in-process — no kernel, no privileges, every platform. Where drivers get written and tested.

Errors pass through

Throw what node:fs throws. fsError("ENOENT") builds an error byte-identical to Node's, and it reaches the kernel untranslated.

Capabilities, never faked

What your driver supports is declared or inferred from its shape. Anything unsupported answers ENOSYS/ENOTSUP instead of pretending.

Kernel caching you control

Attribute and entry timeouts are worth 10–15× on a real workload, and notifyInvalInode() drops a cache the moment your storage changes.

mountx  Write a filesystem in JavaScript, mount it as a real folder.