Skip to content

SynState

A lightweight, glitch-free state management library for TypeScript/JavaScript. Simple global state that scales to complex async pipelines — with built-in debounce, switchMap, and more. Fully compatible with React Compiler.

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.

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.