Getting Started
Welcome to SoulState! This guide will walk you through creating a systems-grade store and connecting it to a React component with surgical precision.
1. Installation
Install SoulState via your preferred package manager. SoulState is zero-dependency and optimized for tree-shaking.
npm install soulstate
2. Creating a Systems-Grade Store
A SoulState store is a centralized reactive tree. You create one using createStore.
import { createStore } from 'soulstate';
// 1. Define your systems-grade state
export const store = createStore({
count: 0,
user: { name: 'Alice', status: 'online' },
items: []
});
// 2. Define surgical actions
export const actions = {
increment: () => store.setState(s => ({ count: s.count + 1 })),
updateStatus: (status: string) => store.setState({ user: { ...store.getState().user, status } })
};
Deterministic Propagation
Every setState call is batched via a deterministic microtask scheduler. If you call increment 10 times synchronously, SoulState will trigger exactly one propagation cycle.
3. Surgical React Integration
Use the useStore hook to subscribe to specific data slices. SoulState uses a Reusable Tracking Proxy to identify exactly which keys your component depends on.
import { useStore } from 'soulstate/react';
import { store, actions } from './store';
export function UserStatus() {
// This component surgically tracks 'user.status'
// Changes to 'count' or 'items' will NEVER trigger a re-render
const status = useStore(store, s => s.user.status);
return (
<div>
<p>Status: {status}</p>
<button onClick={() => actions.updateStatus('away')}>Set Away</button>
</div>
);
}
Why this is different
In a global broadcast library (like Zustand), changing count would still trigger a selector re-run for UserStatus. In SoulState, the Invalidation Graph knows that UserStatus does not care about count and skips it entirely at the engine level.
4. Derived State with computed
For complex derived data, use store.computed. These nodes are part of the core reactive graph, providing cached, glitch-free, and topologically stable values.
// Create a derived node
const isOnline = store.computed(s => s.user.status === 'online');
// Access value (lazily computed and cached)
console.log(isOnline.value); // true
// Subscribe to it in React
function StatusBadge() {
const online = useStore(store, () => isOnline.value);
return <span>{online ? '🟢' : '⚪'}</span>;
}
Systems-Grade Observability
Need to see how your store is performing? Enable instrumentation:
store.enableInstrumentation({ onFlush: (d) => console.log(`Flush took ${d}ms`) });