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-secure-store

56 linesSource

Persist small secrets with Expo SecureStore via @stainless-code/persist/backends/secure-store. ~2KB/key — use partialize; async → useHydrated.

SecureStore backend

For tokens / small secrets, not full app state (~2KB/key). Async → gate UI. Keys sanitized to /^[\w.-]+$/ (: → _).

Install

shell
bun add @stainless-code/persist expo-secure-store zustand

Peers: expo-secure-store >=12.0.0; example uses zustand (any ./sources/* adapter works).

Minimal wiring

ts
import { create } from "zustand";
import { createSecureStoreStorage } from "@stainless-code/persist/backends/secure-store";
import { persistStore } from "@stainless-code/persist/sources/zustand";

type Auth = { token: string };
const useAuth = create<Auth>(() => ({ token: "" }));
const storage = createSecureStoreStorage<string>()!;
persistStore(useAuth, {
  name: "auth:token:v1",
  storage,
  partialize: (s) => s.token,
});

Common mistakes

  • Storing large documents — wrong backend.
  • Skipping partialize.
  • Assuming colon keys are stored literally.

API surface

  • createSecureStoreStorage() · secureStoreStateStorage()

See also: persist-mmkv; persist-encrypted.