React Integration
Select nusm state in React with useSyncExternalStore and configurable equality.
React bindings live in nusm/react, keeping React out of the core package path.
import { useStore } from "nusm/react";Select the smallest value you need
const displayName = useStore(
accountStore,
(state) => state.profile.displayName,
);The selector runs against the current store state. By default, the selected value uses shallow equality from fast-equals to preserve the previous reference when the result is equivalent.
Read the entire state
The selector is optional:
const state = useStore(accountStore);Prefer a narrow selector for components that only need one field.
Deep equality
Set equal: true when a selector produces a nested structure whose deep equality should preserve its previous reference:
const profile = useStore(accountStore, (state) => state.profile, {
equal: true,
});Deep comparison has a cost. Use it deliberately rather than as a default for every selector.
Hydration-aware rendering
Persistence begins immediately when the store is created. If your view cannot show initial state before hydration, gate that view on ready:
import { useEffect, useState } from "react";
import { useStore } from "nusm/react";
import { preferencesStore } from "./stores/preferences";
export function Preferences() {
const [ready, setReady] = useState(preferencesStore.isReady);
const theme = useStore(preferencesStore, (state) => state.theme);
useEffect(() => {
void preferencesStore.ready.then(() => setReady(true));
}, []);
if (!ready) return <p>Restoring preferences…</p>;
return <p>Theme: {theme}</p>;
}Create stores outside component render so identity, hydration, subscriptions, and persistence scheduling remain stable.