mountx logomountx

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 on Linux (no root needed), NFSv3 on macOS.
await using mounted = await mount(driver, "/mnt/point");

mounted.transport; // "fuse" | "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, two transports

    FUSE where FUSE works, NFSv3 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 either transport.

  • Pure JavaScript

    Zero runtime dependencies, both 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 8–15× on a real workload, and notifyInvalInode() drops a cache the moment your storage changes.

mountx logo

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