Introduction
SynState is a lightweight, high-performance 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.
“SynState” is named after “Synchronized + State.” Derived values are always kept in sync through glitch-free propagation — no inconsistent intermediate states. (Details: How SynState Solved the Glitch)
Features
Section titled “Features”- 🎯 Simple State Management: Easy-to-use
createStateandcreateReducersimilar to ReactuseState/useReducer, but for global state. - ⚡ High Performance: Glitch-free propagation — up to 30× faster than Jotai and 16× faster than Redux. See benchmarks.
- 🚀 Lightweight: ~4.5 kB min+gzip with only one external runtime dependency (ts-data-forge).
- 🔧 Built-in Async Operators:
debounce,throttle,switchMap, and more — handle complex async flows in a unified, declarative API without external libraries. - ⚛️ React-Optimized: Fully compatible with React Compiler.
synstate-react-hookslets 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 (
synstate-react-hooks/synstate-preact-hooks) are available. For Preact, a Preact Signals integration (synstate-preact-signals) is also provided for fine-grained DOM updates without component re-renders.
Quick Example
Section titled “Quick Example”With a single call to createState, you can add global state to your application:
import { createState } from 'synstate';
// Create a reactive stateconst [state, setState] = createState(0);
// Subscribe to changesstate.subscribe((count) => { console.log(count); // 0, 1});
// Update statesetState(1);createState creates a reactive state and a setter function. Subscribers are called immediately with the initial value, and again whenever the state is updated.
createState also returns a third element with additional utilities:
const [ state, setState, { updateState, resetState, getSnapshot, initialState },] = createState(0);
updateState((prev) => prev + 1); // update using a function of the previous valueresetState(); // reset to initial value (0)getSnapshot(); // read current value synchronously (0)initialState; // the initial value passed to createState (0)Deriving Values with pipe
Section titled “Deriving Values with pipe”SynState’s power comes from composing Observables. Use pipe to derive new values and combine to merge multiple sources:
import { combine, createState, type InitializedObservable, map,} from 'synstate';
const [count, setCount] = createState<number>(0);
// Read the current valueconsole.log(count.getSnapshot().value); // 0
// Derive new Observables using pipeconst doubled: InitializedObservable<number> = count.pipe(map((n) => n * 2));
// Combine multiple Observablesconst combined: InitializedObservable<string> = combine([count, doubled]).pipe( map(([c, d]) => `(${c}, ${d})`),);
// Subscribe to changescount.subscribe((value) => { console.log('count:', value); // 0, 1, 2, 3});
doubled.subscribe((value) => { console.log('doubled:', value); // 0, 2, 4, 6});
combined.subscribe((value) => { console.log(value); // "(0, 0)", "(1, 2)", "(2, 4)", "(3, 6)"});
// Update statesetCount(1);setCount(2);setCount(3);For a deeper understanding of how this declarative model works — and why it is better than managing state imperatively — see Declarative State Management.
Using with React
Section titled “Using with React”createState must be called at module scope (outside of components). SynState provides synstate-react-hooks, a companion package that bridges Observables and React:
import type * as React from 'react';import { createState } from 'synstate-react-hooks';
const [useUserState, setUserState] = createState({ name: '', email: '',});
const UserProfile = (): React.JSX.Element => { const user = useUserState();
return ( <div> <p>{`Name: ${user.name}`}</p> <button onClick={() => { setUserState({ name: 'Alice', email: 'alice@example.com', }); }} > {'Set User'} </button> </div> );};For more details, see React Integration.
Next Steps
Section titled “Next Steps”- Installation — Install SynState and optional companion packages.
- Why SynState? — Design philosophy, glitch-free guarantees, and use cases.
- Declarative State Management — Understand the reactive programming model with concrete examples.
- React Integration — Use SynState with React.