Skip to content

Persisted Preact signals for localStorage, sessionStorage, IndexedDB, cookies, and memory.

Live examplesTry each storage driver — values update instantly
import { persistedSignal } from "@kamod-ch/signals";

const theme = persistedSignal("hero-theme", "dark", {
  storage: "local",
});
Try itlocal

Survives browser restarts — ideal for theme, density, or dashboard preferences.

value "dark"

Quick start

pnpm add @kamod-ch/signals @preact/signals preact
Install in one command, then choose the right storage strategy for preferences, drafts, SSR hints, or fallback state.

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.

Persistence

Simple persistence

Start with a single signal and persist it into localStorage, sessionStorage, cookie, memory, or IndexedDB.

DX

Framework friendly

Use persistedSignal() for globals or usePersistedSignal() inside components.

SSR

SSR-aware cookies

Read and write cookies through createCookieContext() on the server without touching browser APIs.

Sync

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

local

Keep UI choices across browser restarts. Perfect for theme, density, or dashboard preferences.

value "dark"

Temporary UI state

session

Store values only for the active tab, for example open sidebars or draft filters.

value true

Ephemeral state

memory

Best for environments without browser storage or when you only need a reactive in-memory fallback.

value 1

Larger client data

indexeddb

IndexedDB hydrates asynchronously and fits bigger client-side payloads like drafts, cached lists, or offline data.

value "draft-a"

Shared key sync

memory

Two controllers with the same storage/key pair share a single reactive state.

value {
  "first": 0,
  "second": 0
}

Typical use cases#

Use case

Theme & preferences

Persist color mode, density, dismissed banners, and dashboard layout choices.

Use case

Per-tab UI state

Keep sidebars, filters, and temporary flows only for the current browser tab.

Use case

SSR-visible values

Store locale or similar hints in cookies so the server can read them too.

Use case

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.