Registry / messaging / ws-sync

ws-sync

JSON →
library0.8.3jsnpmunverified

A state synchronization library for React frontends that uses a WebSocket and JSON/JSON Patch protocol to keep Zustand stores in sync with a backend (Python reference implementation available). Current stable version is 0.8.3. Release cadence is irregular; actively maintained as of 2025. Key differentiators: follows Zustand's philosophy of state outside React, uses Immer for efficient JSON Patch generation, minimal boilerplate with a synced() middleware, and provides a lightweight Session object for WebSocket management. Requires React 18+, React DOM 18+, and Zustand 5.x. Peer dependencies include zustand@^5.0.0.

npm install ws-sync
INSTALL
IMPORT
SIG · WS-SYNC
W
ws-sync
messagingjavascriptv0.8.3
harness data pending
Install & Compatibility
Where this runs

No compatibility data collected yet for this library.

Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

Session
import { Session } from 'ws-sync'
const Session = require('ws-sync').Session
ESM-only; CJS require() works but is discouraged. TypeScript types are included.
synced
import { synced } from 'ws-sync'
import synced from 'ws-sync'
synced is a named export, not default. Common mistake: trying default import.
useSync
import { useSync } from 'ws-sync'
Optional hook for component-level sync usage if needed.

Creates a WebSocket session and a Zustand store synced with the backend, then uses it in a React component.

import { Session, synced } from 'ws-sync'; import { create } from 'zustand'; const session = new Session({ url: process.env.WS_URL ?? 'ws://localhost:8000/ws', label: 'Backend', toast: null, }); session.connect(); interface Notes { notes: { id: string; title: string; content: string }[]; currentNoteId: string | null; } export const useNotes = create<Notes>()( synced( () => ({ notes: [], currentNoteId: null, }), { key: 'Notes', session } ) ); function NotesList() { const notes = useNotes((s) => s.notes); const noteId = useNotes((s) => s.currentNoteId); return ( <ul> {notes.map((n) => ( <li key={n.id} className={n.id === noteId ? 'active' : ''}> {n.title} </li> ))} </ul> ); }
Debug
Known issues
breakingRequires zustand@^5.0.0; older versions (e.g., 4.x) are incompatible
fix
Install zustand@^5.0.0: npm install zustand@5
affects: >=0.0.0
breakingReact 18+ required; will not work with React 17 or earlier
fix
Upgrade React to v18+
affects: >=0.0.0
gotchaCalling sync() without a prior set() may send empty patches or cause unexpected behavior; always call set() before sync()
fix
Ensure set() is called inside the same function before sync(). Example: set({ currentNoteId: id }); sync();
affects: >=0.0.0
gotchaThe synced middleware expects a unique 'key' per store. Using duplicate keys can cause cross-store data corruption.
fix
Assign a unique key to each synced store (e.g., 'Notes', 'Todos').
affects: >=0.0.0
deprecatedIn earlier versions, Session.connect() was called automatically. Now it must be called explicitly after creating the Session.
fix
Call session.connect() explicitly: const session = new Session(...); session.connect();
affects: <0.4.0
Errors
Common errors & fixes
Module not found: Can't resolve 'ws-sync'
Package not installed or missing from node_modules
fix
Run: npm install ws-sync zustand (and ensure peer deps are met)
TypeError: session.connect is not a function
Session instance created but not connected, or method called before async init
fix
Ensure session.connect() is called after new Session(...), and wait for the connection promise if using async/await.
Uncaught Error: [zustand] middleware must be a function
synced() middleware incorrectly imported or used as default import
fix
Use named import: import { synced } from 'ws-sync'
React Hook "useNotes" is called conditionally
Calling a Zustand hook inside a condition or after early return
fix
Ensure hooks are called at the top level of a React component, not inside loops, conditions, or nested functions.
Upgrade
Version history
0.8.3latest on npm
Audit
Dependencies
reactoptionalPeer dependency for React hooks and component integration
react-domoptionalPeer dependency for React DOM rendering
zustandrequiredPeer dependency for state management; synced middleware wraps Zustand's create()
Agent activity
34 hits · last 30 days
node
30
OpenAI (training)
1
Resources
ws-sync — npm install ws-sync · libregistry