- Start Date: 2025-12-30
- RFC PR: (leave this empty)
- React Issue: (leave this empty)
Introduce createStore API for creating headless React instances that accept hooks and expose state for external consumption—enabling React's full hook system for state management outside components.
const counterStore = createStore(() => {
const [count, setCount] = useState(0);
useEffect(() => {
console.log('Count changed:', count);
}, [count]);
const increment = () => setCount(c => c + 1);
return {
count,
increment,
};
});
// Outside React
counterStore.subscribe(state => console.log(state.count));
counterStore.current.increment(); // Count changed: 1
// Inside React
function Counter() {
const { count, increment } = useStore(counterStore);
return <button onClick={increment}>{count}</button>;
}-
Unified mental model: Same hooks API for component state and global state.
-
Full React capabilities: Unlike simplified state libraries, headless stores retain effects, memoization, Suspense, and refs.
interface Store<T> {
readonly current: T;
subscribe(listener: (state: T) => void): () => void;
destroy(): void;
}Most hooks work as in components, with some exceptions: useContext always returns the default value (no Provider hierarchy exists in a headless instance), use(context) performs the same way, use(promise) should directly throw an error.
useStore consumes store state using useSyncExternalStore like tech internally.
- Overlap:
useSyncExternalStorealready handles external state; this adds another pattern - Complexity: Requires maintaining a headless reconciler that stays in sync with React internals
- Misuse potential: Memory leaks if
destroy()not called;useContextbehavior may surprise users - Ecosystem impact: May fragment state management library ecosystem
just do nothing.
Non-breaking addition as it do not make changes to existing APIs. Can create a polyfill based on react-nil or similar libraries.
"React hooks, but for global state".
- How should
useTransition/useDeferredValuebehave without UI? - May provide some degree of
use(promise)support. - DevTools integration for headless store state?