Skip to content

@stainless-code/persist

Hydration-aware persistence for any reactive store — zero-dep persistSource core; codecs, backends, cross-tab transport, source + framework hydration adapters ship as opt-in recipes

persist-node-fs

42 linesSource

Persist to the filesystem with @stainless-code/persist/backends/node-fs (nodeFsStateStorage). StateStorage only — compose createStorage + codec; one file per key with hash suffix.

Node filesystem backend

Exports nodeFsStateStorage({ dir }) only — compose with createStorage + a codec. One file per key; sanitized name + djb2 hash suffix (collision-safe). Refuses keys that sanitize to . / .. / "". ENOENT → null / no-op remove.

Minimal wiring

ts
import { createStorage, jsonCodec } from "@stainless-code/persist";
import { nodeFsStateStorage } from "@stainless-code/persist/backends/node-fs";

const storage = createStorage<Prefs>(
  () => nodeFsStateStorage({ dir: "./.persist" }),
  jsonCodec(),
);

No optional peer for this backend — uses node:fs. Richer graphs → persist-seroval as the codec.

Common mistakes

  • Expecting a create*Storage PersistStorage factory.
  • Assuming sanitize alone makes unique paths — the hash suffix is required for collisions.
  • Path-traversal keys — refused after sanitize.

API surface

  • nodeFsStateStorage({ dir }) → StateStorage<string>