nusm axolotlnusm
Storage Adapters

localStorage

Persist small durable state across reloads with same-origin browser storage.

import { createLocalStorageAdapter, createNusmStore } from "nusm";

const preferences = createNusmStore(
  { density: "comfortable", theme: "system" },
  {
    adapter: createLocalStorageAdapter(),
    persist: { strategy: "entire" },
    storeId: "preferences",
    sync: {
      validator: (candidate) =>
        typeof candidate === "object" &&
        candidate !== null &&
        typeof (candidate as { density?: unknown }).density === "string" &&
        typeof (candidate as { theme?: unknown }).theme === "string",
    },
  },
);

Options

interface StorageAdapterOptions {
  storage?: StorageLike;
  prefix?: string;
  serialize?: (value: unknown) => string;
  deserialize?: (raw: string) => unknown;
  pacer?:
    | false
    | {
        wait?: number;
        maxWait?: number;
        leading?: boolean;
        trailing?: boolean;
      };
}
OptionDefaultPurpose
storagewindow.localStorageInject another synchronous Storage-like target
prefix"nusm"Namespace all physical keys
serializesuperjson.stringifyEncode state before writing
deserializesuperjson.parseDecode matching stored values
pacertrailing, 50 msControl write scheduling

Custom namespace and serializer

const adapter = createLocalStorageAdapter({
  prefix: "acme-state",
  serialize: JSON.stringify,
  deserialize: JSON.parse,
  pacer: { trailing: true, wait: 150 },
});

The current scheduler uses wait, leading, and trailing; maxWait remains in the public type but is not forwarded yet.

Always change serializer and deserializer together. Existing values written in another format need an explicit migration or a compatible decoder.

External updates and synchronization

The adapter can translate browser storage events into set or remove events. nusm continues attaching that adapter listener whenever it is provided. Authenticated browser synchronization is configured independently through sync; see Authenticated synchronization. Remote values pass the receiving store validator and persist without echoing.

Constraints

  • Browser storage is synchronous; keep values reasonably small.
  • Quota and privacy-mode failures reach onError.
  • Any script on the same origin can read local storage. Do not put secrets there.
  • Construct the default adapter only where window.localStorage exists.

On this page