Revision-based ordering
Monotonic revisions ensure updates apply in correct order. Stale events are automatically rejected.
Learn about protocol
Revision-based ordering âĒ Multi-framework âĒ Persistence & cross-tab sync
npm install @statesync/corepnpm add @statesync/coreyarn add @statesync/core# Persistence (caching, migrations, cross-tab sync)
npm install @statesync/persistence
# Framework adapter (pick one)
npm install @statesync/redux # React + Redux / RTK
npm install @statesync/zustand # React + Zustand
npm install @statesync/jotai # React + Jotai
npm install @statesync/mobx # MobX
npm install @statesync/pinia # Vue + Pinia
npm install @statesync/valtio # React + Valtio
npm install @statesync/svelte # Svelte
npm install @statesync/vue # Vue (reactive/ref)
# Transport adapter
npm install @statesync/tauri # Tauri v2Yes, if you have:
| Scenario | Problem state-sync solves |
|---|---|
| Multi-window desktop app (Tauri, Electron) | State diverges between windows/processes |
| Multi-process architecture | Main â renderer processes lose sync |
| Backend pushes state updates | Events arrive out of order, UI flickers |
| State must survive restart | Need persistence with proper invalidation |
No, if you have:
Stale updates are rejected. Rapid events are merged. State stays consistent. Learn more â
Sync a Zustand store across browser tabs with persistence:
import { createRevisionSync } from '@statesync/core';
import { createZustandSnapshotApplier } from '@statesync/zustand';
// 1. Listen for "state changed" events from other tabs
const channel = new BroadcastChannel('my-sync');
const subscriber = {
async subscribe(handler) {
channel.onmessage = (e) => handler(e.data);
return () => channel.close();
},
};
// 2. Fetch current state
const provider = {
async getSnapshot() {
const raw = localStorage.getItem('my-state');
return raw ? JSON.parse(raw) : { revision: '0', data: {} };
},
};
// 3. Wire it together
const sync = createRevisionSync({
topic: 'my-state',
subscriber,
provider,
applier: createZustandSnapshotApplier(useMyStore),
});
await sync.start();