Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/christianbaroni/stores/llms.txt

Use this file to discover all available pages before exploring further.

createBaseStore is the foundational store factory in @storesjs/stores. It creates a local, synchronous store from a state creator function and returns a store object that exposes getState, setState, subscribe, and getInitialState. When a storageKey is provided through the options, the store also gains a .persist namespace with hydration and storage-management utilities. In the React build the returned store is also callable as a hook, letting you subscribe to a slice of state with an optional selector and equality function.

Signature

function createBaseStore<S>(createState: StateCreator<S>): Store<S>

function createBaseStore<S, PersistedState extends Partial<S>, PersistReturn extends void | Promise<void>>(
  createState: StateCreator<S>,
  options: BaseStoreOptions<S, PersistedState, PersistReturn>
): Store<S, PersistedState, PersistReturn>
The PersistReturn type parameter controls whether setState is synchronous (void) or asynchronous (Promise<void>), which is inferred automatically from the storage adapter you provide.

StateCreator<S>

The state creator is a function called once at store construction time. It receives three arguments and must return the initial state object S.
type StateCreator<S> = (
  set: SetState<S>,
  get: () => S,
  store: StoreApi<S>
) => S
set
(update: Partial<S> | ((state: S) => Partial<S>), replace?: boolean) => void
required
Updates the store’s state. Accepts a partial state object, a full state replacement object (when replace is true), or an updater function that receives the current state and returns an updated slice.
get
() => S
required
Returns the current state snapshot. Useful for reading current values inside action functions before or after calling set.
store
StoreApi<S>
required
The raw store object. Gives you access to getState, setState, and subscribe from within the state creator, which can be passed to utilities or closures that need a stable store reference.

Parameters

createState
StateCreator<S>
required
The state creator function described above. This is the only required argument.
options
BaseStoreOptions<S, PersistedState, PersistReturn>
Optional configuration object. Accepts the PersistConfig fields below plus an optional sync field. Providing storageKey activates persistence and adds .persist to the returned store.
sync
SyncConfig<S> | string | true
Enables cross-tab or cross-context state synchronization. Pass true to inherit the sync key from storageKey, a plain string to use a custom key, or a SyncConfig object for full control. This option is a sibling of the PersistConfig fields, not nested inside them.

Return Value

createBaseStore returns a Store<S> (non-persisted) or Store<S, PersistedState, PersistReturn> (persisted). Both variants expose the same core store API.

Store API

getState
() => S
Returns the current state snapshot synchronously. Safe to call anywhere — inside or outside React.
setState
(update: Partial<S> | ((state: S) => Partial<S>), replace?: false) => PersistReturn
Merges a partial state update into the current state. When replace is true, the second overload replaces the entire state object. For stores backed by async storage, returns a Promise<void> that resolves once the state has been written to disk.
subscribe
SubscribeOverloads<S>
Subscribes to state changes. Returns an unsubscribe function.
getInitialState
() => S
Returns the initial state object produced by createState at construction time, before any setState calls. Useful for resetting a store to its defaults.

.persist (persisted stores only)

When a storageKey is provided, the returned store exposes a .persist namespace.
persist.hasHydrated
() => boolean
Returns true if the initial hydration pass from storage has completed (or if no persisted data was found).
persist.rehydrate
() => Promise<void> | void
Manually triggers a re-read from storage and merges the result into the current state. Returns a promise for async storage backends.
persist.clearStorage
() => void
Removes the persisted entry for this store from storage without modifying the in-memory state.
persist.onHydrate
(listener: (state: S) => void) => () => void
Registers a listener that fires when hydration begins. Returns an unsubscribe function.
persist.onFinishHydration
(listener: (state: S) => void) => () => void
Registers a listener that fires after hydration completes. Returns an unsubscribe function.
persist.getOptions
() => Partial<PersistOptions<S, PersistedState>>
Returns the active persistence options object, including the storage adapter and schema version.
persist.setOptions
(options: Partial<PersistOptions<S, PersistedState>>) => void
Merges new persistence options into the active configuration at runtime. Useful for swapping the storage backend after initialization.
persist.hydrationPromise
() => Promise<void>
Available only for async storage backends. Returns a promise that resolves once the initial hydration pass has finished. Useful for awaiting hydration in setup or test code.
await store.persist.hydrationPromise();

React Hook Usage

In the React build every store is also callable as a hook:
// Subscribe to the full state
const state = store();

// Subscribe to a selected slice
const currency = store(s => s.currency);

// Subscribe with a custom equality function
const items = store(s => s.items, shallowEqual);
Calling the store as a hook inside a component automatically subscribes to the selected state and triggers a re-render when it changes.

Example

import { createBaseStore } from '@storesjs/stores';
import { time } from '@storesjs/stores/utils';

type Settings = {
  currency: string;
  locale: string;
  darkMode: boolean;
  setCurrency: (currency: string) => void;
  setLocale: (locale: string) => void;
  toggleDarkMode: () => void;
};

export const settingsStore = createBaseStore<Settings, Pick<Settings, 'currency' | 'locale' | 'darkMode'>>(
  set => ({
    currency: 'USD',
    locale: 'en-US',
    darkMode: false,
    setCurrency: currency => set({ currency }),
    setLocale: locale => set({ locale }),
    toggleDarkMode: () => set(s => ({ darkMode: !s.darkMode })),
  }),
  {
    storageKey: 'app.settings',
    version: 2,
    partialize: ({ currency, locale, darkMode }) => ({ currency, locale, darkMode }),
    migrate: (persisted, version) => {
      // v1 stored `theme` instead of `darkMode`
      if (version < 2 && 'theme' in persisted) {
        const { theme, ...rest } = persisted as typeof persisted & { theme: string };
        return { ...rest, darkMode: theme === 'dark' };
      }
      return persisted;
    },
    persistThrottleMs: time.seconds(2),
  }
);
// Inside a React component
function CurrencyPicker() {
  const currency = settingsStore(s => s.currency);
  const setCurrency = settingsStore(s => s.setCurrency);

  return (
    <select value={currency} onChange={e => setCurrency(e.target.value)}>
      <option value="USD">USD</option>
      <option value="EUR">EUR</option>
    </select>
  );
}
// Outside React
const { currency, locale } = settingsStore.getState();

const unsubscribe = settingsStore.subscribe(
  s => s.currency,
  (next, prev) => console.log('currency changed', prev, '->', next),
  { fireImmediately: true }
);

Build docs developers (and LLMs) love