Persisted Preact signals for localStorage, sessionStorage, IndexedDB, cookies, and memory.
import { persistedSignal } from "@kamod-ch/signals";
const theme = persistedSignal("hero-theme", "dark", {
storage: "local",
});Survives browser restarts — ideal for theme, density, or dashboard preferences.
Quick start
pnpm add @kamod-ch/signals @preact/signals preact
Why @kamod-ch/signals#
@kamod-ch/signals adds persistence to Preact signals without changing how signals feel.
Start with one signal, choose a storage driver, and keep the same simple API.
Simple persistence
Start with a single signal and persist it into localStorage, sessionStorage, cookie, memory, or IndexedDB.
Framework friendly
Use persistedSignal() for globals or usePersistedSignal() inside components.
SSR-aware cookies
Read and write cookies through createCookieContext() on the server without touching browser APIs.
Cross-controller sync
Signals stay in sync when multiple controllers point to the same storage/key pair.
Common examples#
Explore practical scenarios: theme preferences, tab-scoped UI state, SSR-friendly cookie values, memory-only reactive state, IndexedDB-backed drafts, and shared-key synchronization.
Theme preference
localKeep UI choices across browser restarts. Perfect for theme, density, or dashboard preferences.
value "dark"Temporary UI state
sessionStore values only for the active tab, for example open sidebars or draft filters.
value trueCookie-backed locale
cookieUseful when a server should also see the value, for example locale or auth-adjacent hints.
value "de"Ephemeral state
memoryBest for environments without browser storage or when you only need a reactive in-memory fallback.
value 1Larger client data
indexeddbIndexedDB hydrates asynchronously and fits bigger client-side payloads like drafts, cached lists, or offline data.
value "draft-a"Shared key sync
memoryTwo controllers with the same storage/key pair share a single reactive state.
value {
"first": 0,
"second": 0
}Typical use cases#
Theme & preferences
Persist color mode, density, dismissed banners, and dashboard layout choices.
Per-tab UI state
Keep sidebars, filters, and temporary flows only for the current browser tab.
SSR-visible values
Store locale or similar hints in cookies so the server can read them too.
Drafts & cached data
Move larger client-side payloads into IndexedDB with async hydration.
Next step
Get your first persisted signal working in minutes.
Start with the quick setup guide, then compare storage drivers once you have one real example working.