unfs
A filesystem you can put in any key–value store.
import { createFs, initStore, memoryStore } from "unfs";
const fs = createFs(await initStore(memoryStore()));
await fs.mkdir("/docs");
await fs.writeFile("/docs/hello.txt", "hello unfs\n");
await fs.cp("/docs", "/backup", { recursive: true }); // O(1)
const pack = await fs.exportPackBytes("/"); // whole tree, one file
Features
A familiar API
A drop-in node:fs/promises-style surface with node-shaped errors (ENOENT, EEXIST, …), plus a fully synchronous twin.
Bring your own store
Runs over any key–value backend — in-memory, on-disk, Redis, S3. If it can get and put bytes, it can hold a filesystem.
Snapshots for free
Every write is a snapshot, identical content is stored once, and copying a directory is O(1).
Deterministic
The same tree always comes out byte-identical — no timestamps sneak in unless you ask for them.
Portable packs
Export any subtree to a single CARv1 file and import it into another store, hash-verified.
Store-to-store sync
Mirror or pull refs over any byte stream — only the blocks the other side is missing move.
Fast when you need it
Batch bulk writes into one snapshot (50×+ faster) and cache decoded nodes for 20–40× faster reads.
Garbage collection
Mark & sweep with a write-free dry-run, to reclaim superseded snapshots.
Zero dependencies
No runtime deps, no node: imports in the core — strict ESM TypeScript, IPLD-compatible on the wire.