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.