createStorageStore
Creates a reactive nanostore bound to a single storage key.
Signature
function createStorageStore( adapter: StorageAdapter | StorageAdapter[], key: string, options?: StorageStoreOptions,): StorageStore;Parameters
adapter
The storage adapter(s) to use.
| Type | Description |
|---|---|
StorageAdapter | Single adapter |
StorageAdapter[] | Array of adapters for fallback chain |
// Single adaptercreateStorageStore(localStorageAdapter, "key");
// Fallback chaincreateStorageStore([sessionStorageAdapter, localStorageAdapter], "key");key
The storage key to bind to.
| Type | Description |
|---|---|
string | Storage key name |
options
Optional configuration object.
interface StorageStoreOptions { listen?: boolean; defaultValue?: string | null;}| Option | Type | Default | Description |
|---|---|---|---|
listen | boolean | false | Enable cross-tab sync |
defaultValue | string | null | null | Initial fallback value when storage is empty |
Return Value
Returns a StorageStore object:
interface StorageStore { readonly $value: ReadableAtom<string | null>; get: () => string | null; set: (value: string) => void; remove: () => void; sync: () => void; readonly listener: StorageListener;}$value
A nanostores ReadableAtom containing the current value. Use get() and set() methods to modify.
// Subscribe to changesconst unsubscribe = store.$value.subscribe((value) => { console.log(value);});
// Listen (skip initial call)store.$value.listen((value) => { console.log("Changed to:", value);});get()
Returns the current value.
const value = store.get(); // string | nullset(value)
Sets a new value. Writes to all adapters in a fallback chain.
store.set("new value");remove()
Removes the value from storage and resets $value to null.
store.remove();// localStorage.getItem("key") === null// store.get() === nullsync()
Force sync from storage to store. Useful when:
listen: falseand you want to manually refresh- Polling for same-tab changes from other libraries (with
setInterval) - Using adapters without event support (e.g., cookies)
// Manual refresh when listen: falsestore.sync();
// Polling pattern for same-tab changes (not recommended for most cases)const interval = setInterval(() => store.sync(), 1000);listener
Controls cross-tab synchronization.
interface StorageListener { on: () => void; off: () => void; toggle: () => void; readonly $on: ReadableAtom<boolean>;}| Member | Description |
|---|---|
on() | Begin listening for external changes |
off() | Stop listening |
toggle() | Toggle listening state |
$on | Reactive boolean indicating listener status |
Examples
Basic Usage
import { createStorageStore, localStorageAdapter } from "@vp-tw/nanostores-storage";
const usernameStore = createStorageStore(localStorageAdapter, "username");
// Readconsole.log(usernameStore.get()); // null or stored value
// WriteusernameStore.set("Alice");
// RemoveusernameStore.remove();With Default Value (Initial Only)
const themeStore = createStorageStore(localStorageAdapter, "theme", { defaultValue: "system",});
// On first load (storage empty): "system"console.log(themeStore.get());
// After remove() or if deleted from another tab: null (not "system")themeStore.remove();console.log(themeStore.get()); // nullWith Always-On Fallback (Using computed)
import { computed } from "nanostores";
const themeStore = createStorageStore(localStorageAdapter, "theme");
// Always returns a value, never nullconst $theme = computed(themeStore.$value, (v) => v ?? "system");
console.log($theme.get()); // "system" if null, otherwise stored valueWith Cross-Tab Sync
const settingsStore = createStorageStore(localStorageAdapter, "settings", { listen: true, defaultValue: "{}",});
// Automatically updates when changed in other tabssettingsStore.$value.subscribe((value) => { console.log("Settings updated:", value);});With Fallback Chain
const sessionStore = createStorageStore( [sessionStorageAdapter, localStorageAdapter], "session-data", { listen: true },);Manual Listener Control
const store = createStorageStore(localStorageAdapter, "key");
// Start when neededstore.listener.on();console.log(store.listener.$on.get()); // true
// Stop when donestore.listener.off();React Integration
import { useStore } from "@nanostores/react";import { createStorageStore, localStorageAdapter } from "@vp-tw/nanostores-storage";
const counterStore = createStorageStore(localStorageAdapter, "counter", { defaultValue: "0",});
function Counter() { const count = useStore(counterStore.$value); const value = parseInt(count ?? "0", 10);
return <button onClick={() => counterStore.set(String(value + 1))}>Count: {value}</button>;}See Also
- createStorageValuesStore — Monitor all storage keys
- StorageAdapter — Adapter interface
- Cross-Tab Sync — How listening works