Simple State Management
Easy-to-use createState and createReducer similar to React
useState / useReducer for global state.
Simple State Management
Easy-to-use createState and createReducer similar to React
useState / useReducer for global state.
Built-in Async Operators
debounce, throttle, switchMap, and more — handle complex async
flows in a unified, declarative API without external libraries.
Glitch-Free Through Every Operator
Every update is one depth-ordered pass over what it reaches, the ones debounce or switchMap start later included, so no subscriber sees a half-updated graph, and an update costs in proportion to the nodes it reaches rather than the paths between them. Operators on Signals shows what an operator written as an effect loses.
Very Fast
In the benchmark summary, SynState stays within 2.7× of the fastest library in every scenario: the only library measured in all of them whose worst case stays in single digits. See each library’s worst case.
Lightweight
~7.7 kB min+gzip with two external runtime dependencies, one of which depends on the other. Compare it with other libraries.
React-Optimized
Fully compatible with React Compiler. synstate-react-hooks lets you
add global state to any component in just a few lines.
Framework Agnostic
Core library works as-is with vanilla JavaScript, Vue, Svelte, or any framework. For React and Preact, hooks wrappers are available. For Preact, a Preact Signals integration is also provided.
UI on SynState: synstate-dom
synstate-dom binds Observables straight to the DOM, so the whole UI, async steps included, is one SynState graph. A component runs once, with no virtual DOM and no compiler.
Typed Routes: synstate-router
synstate-router checks every destination, path parameter and search parameter with the type checker, and keeps its state in SynState Observables. It has bindings for React and synstate-dom, and is not on npm yet.