Redux State Sync

raw JSON →
3.1.4 verified Sat Apr 25 auth: no javascript

A lightweight middleware for syncing Redux state across browser tabs using the Broadcast Channel API with a fallback via pubkey's broadcast-channel. Current stable version 3.1.4. Released under MIT license, maintained actively. Key differentiator: minimal configuration, automatic tab synchronization, and built-in state initialization from other tabs. Incompatible with functions in action payloads due to structured clone algorithm.

error Error: Actions must be plain objects. Use custom middleware for async actions.
cause An action with a function payload is dispatched, which violates serialization requirement.
fix
Remove functions from action payloads or serialize them before dispatch.
error TypeError: store.dispatch is not a function
cause initMessageListener or initStateWithPrevTab is called before the store is fully created or passed incorrectly.
fix
Ensure store is passed directly: initStateWithPrevTab(store); do not wrap store in another function.
error Module not found: Can't resolve 'redux-state-sync'
cause Package not installed; or using bundler with incorrect module resolution.
fix
Run npm install redux-state-sync and ensure node_modules is present.
breaking In v3, initMessageListener is no longer needed if using initStateWithPrevTab; calling both can cause double initialization.
fix Use initStateWithPrevTab(store) alone; remove initMessageListener(store) if present.
gotcha Function references in action payloads will cause errors because BroadcastChannel uses structured clone algorithm which does not support functions.
fix Ensure all action payloads are plain serializable objects.
gotcha When using redux-persist, PERSIST and REHYDRATE actions must be blacklisted to avoid infinite loops.
fix Add 'persist/PERSIST' and 'persist/REHYDRATE' to the blacklist config.
breaking TypeScript types are not bundled; you must install @types/redux-state-sync separately (now deprecated, consider adding own types).
fix Install @types/redux-state-sync or define your own types.
gotcha BroadcastChannel may not be supported in older browsers (e.g., Safari < 15.4). The fallback via broadcast-channel library works but has performance implications.
fix Check compatibility or use alternatives if targeting very old browsers.
npm install redux-state-sync
yarn add redux-state-sync
pnpm add redux-state-sync

Shows full setup: create middleware, wrap reducer, init state from previous tab, and blacklist an action type.

import { createStore, applyMiddleware, combineReducers } from 'redux';
import { createStateSyncMiddleware, initStateWithPrevTab, withReduxStateSync } from 'redux-state-sync';

const config = { blacklist: ['TOGGLE_TODO'] };
const middlewares = [createStateSyncMiddleware(config)];

const rootReducer = combineReducers({
  todos: (state = [], action) => state,
  visibilityFilter: (state = 'SHOW_ALL', action) => state
});

const store = createStore(
  withReduxStateSync(rootReducer),
  applyMiddleware(...middlewares)
);

initStateWithPrevTab(store);

// Now dispatch actions normally; other tabs will sync automatically