Introduction
React state hooks backed by an external store.
@ilokesto/state
@ilokesto/state is the React-facing layer on top of @ilokesto/store. It does not invent a new state container. Instead, it takes an external store model and gives you a hook API that fits naturally into React through useSyncExternalStore.
That framing matters because it explains most of the package in one sentence: the store stays outside React, while reads and subscriptions are expressed as hooks.
What this package gives you
- A single
create()entry point for turning state or a vanilla store into a React hook. - Two usage modes: plain state mode and reducer mode.
- Selector-based subscriptions that keep reads narrow.
- Imperative accessors like
writeOnly()for actions outside components. - Composable store-level middleware for logging, persistence, validation, and debugging.
What it intentionally does not give you
- No provider-first architecture.
- No Zustand-style initializer function.
- No separate custom equality API for selectors.
- No attempt to hide that there is a real store under the hook.
Installation
npm install @ilokesto/stateQuick Look
import { create } from '@ilokesto/state';
const useCounter = create({ count: 0 });
function Counter() {
const [count, setState] = useCounter((state) => state.count);
return (
<button onClick={() => setState((prev) => ({ ...prev, count: prev.count + 1 }))}>
{count}
</button>
);
}This small example already shows the core shape:
create()builds a hook from external state,- the selector decides what the component reads,
- the writer still updates the full store state.
If you are new to the package, start with Quick Start.
- Read Mental Model if you want to understand why the store lives outside React.
- Read Selectors if the selector/writer split is the part that still feels strange.
- Read Existing Store if you already own a vanilla
Storeand only need the React binding layer.