Getting started
Voltix is a fine-grained state manager for React. You create a store that holds a flat object of keys, and components subscribe to the individual keys they read. Writing one key re-renders only the components reading that key.
Install
npm i @zaatar-tech/voltix
react is the only peer dependency. The package is about 4.4 KB gzipped and ships its own types.
Your first store
Create a store once, at module scope, from an initial state object. It lives outside React: any module can read or write it, and there is no provider to set up.
import { createStore } from '@zaatar-tech/voltix';
export const store = createStore({
count: 0,
step: 1,
});
Every key in the initial object becomes part of the store's typed shape. Reading or writing a key that does not exist is a compile error.
Read one key with useStoreKey
useStoreKey subscribes to one key and returns its value. The component re-renders only when that key changes.
import { useStoreKey } from '@zaatar-tech/voltix';
import { store } from './store';
function Count() {
const count = useStoreKey(store, 'count');
return <span>{count}</span>;
}
Read several keys with useStoreSelector
For more than one key, useStoreSelector takes an array of keys and returns just those keys. The component re-renders when any of them changes.
import { useStoreSelector } from '@zaatar-tech/voltix';
import { store } from './store';
function Status() {
const { count, step } = useStoreSelector(store, ['count', 'step']);
return <span>{count} (step {step})</span>;
}
The selector is always an array: key strings, plus { key: compareFn } entries when a key needs its own comparison. See useStoreSelector.
Pre-bind a hook with createStoreHook
createStoreHook binds the store into a hook once, so components stop passing it around. Types are inferred from the store.
import { createStoreHook } from '@zaatar-tech/voltix';
import { store } from './store';
export const useCounter = createStoreHook(store);
function Controls() {
const { count, step } = useCounter(['count', 'step']);
return <span>{count} / {step}</span>;
}
A complete counter
import { createStore, useStoreKey } from '@zaatar-tech/voltix';
const store = createStore({ count: 0 });
function Counter() {
const count = useStoreKey(store, 'count');
return (
<div>
<button onClick={() => store.increment('count', -1)}>-</button>
<span>{count}</span>
<button onClick={() => store.increment('count')}>+</button>
</div>
);
}
increment adds to a numeric key (default amount is 1). The type system allows it only on keys whose value is a number. Writing to the store from an event handler, an effect, or any module updates every subscribed component.
Next steps
- Walkthrough builds one app end to end, from a single store to a composed tree.
- Core concepts explains per-key subscriptions, identity-stable state, equality, and batching.
- Composition covers nesting stores and lookups (a store per id), navigated with
selectandat. - Guides covers actions, contracts, derived keys, middleware, persistence, and reacting outside React.
- Patterns shows real-world recipes: sending requests, polled live updates, and a live table.
- API reference documents every export and every store method.