Providers
Storage providers are the low-level adapters that read and write to a specific storage backend. You can use the built-in providers or create your own.
Built-in providers
| Provider | Backend | Sync event |
|---|---|---|
localStorageProvider | globalThis.localStorage | storage (cross-tab) |
memoryStorageProvider | in-memory Map | none |
sessionStorageProvider | globalThis.sessionStorage | none |
urlSearchParamsProvider | URL search params | popstate |
urlSearchParamsInHashProvider | URL hash params | hashchange |
localStorageProvider and sessionStorageProvider resolve their globalThis.*Storage backend lazily on each access instead of capturing it when the module is imported. This makes them safe to import before a browser-like global is available, and lets tests or non-DOM runtimes provide storage later.
Provider factories
All built-in providers also have factory functions:
createNoopProvider()createLocalStorageProvider()createMemoryStorageProvider()createSessionStorageProvider()createUrlSearchParamsProvider(options?)createUrlSearchParamsInHashProvider(options?)
Use the storage-backed factories when you want a fresh provider instance instead of the default singleton export.
The URL-based factories accept a push option to customize navigation behavior. They check for a browser context when the provider is created. If window.location or window.history is unavailable, they return a no-op provider instead of throwing.
import {
createLocalStorageProvider,
createMemoryStorageProvider,
createNoopProvider,
createSessionStorageProvider,
createUrlSearchParamsProvider,
createUrlSearchParamsInHashProvider,
} from '@studiometa/js-toolkit/utils';
const noopProvider = createNoopProvider();
const localProvider = createLocalStorageProvider();
const memoryProvider = createMemoryStorageProvider();
const sessionProvider = createSessionStorageProvider();
// Uses pushState instead of the default replaceState
const pushProvider = createUrlSearchParamsProvider({ push: true });
const pushHashProvider = createUrlSearchParamsInHashProvider({ push: true });Custom providers
Implement the StorageProvider interface to create a custom provider:
import { createStorage } from '@studiometa/js-toolkit/utils';
import type { StorageProvider } from '@studiometa/js-toolkit/utils';
const cookieProvider: StorageProvider = {
// Optional: DOM event name for external sync
syncEvent: undefined,
get(key: string): string | null {
const match = document.cookie.match(new RegExp(`(?:^|; )${key}=([^;]*)`));
return match ? decodeURIComponent(match[1]) : null;
},
set(key: string, value: string): void {
document.cookie = `${key}=${encodeURIComponent(value)}; path=/`;
},
remove(key: string): void {
document.cookie = `${key}=; path=/; max-age=0`;
},
has(key: string): boolean {
return this.get(key) !== null;
},
keys(): string[] {
return document.cookie
.split('; ')
.filter(Boolean)
.map((c) => c.split('=')[0]);
},
clear(): void {
for (const key of this.keys()) {
this.remove(key);
}
},
};
const storage = createStorage({ provider: cookieProvider });The syncEvent property
Providers can declare a syncEvent string to indicate which DOM event should trigger re-reading values for subscribed keys. When set, createStorage will automatically listen to this event on window and notify subscribers.
'storage'— for cross-tab sync (localStorage)'popstate'— for back/forward navigation (URL search params, browser-only)'hashchange'— for hash changes (URL hash params, browser-only)- Any custom event name
undefined— no automatic sync (used bysessionStorageProvider)