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.
Common errors
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.
Warnings
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.
Install
npm install redux-state-sync yarn add redux-state-sync pnpm add redux-state-sync Imports
- createStateSyncMiddleware wrong
const createStateSyncMiddleware = require('redux-state-sync').createStateSyncMiddleware;correctimport { createStateSyncMiddleware, initMessageListener, initStateWithPrevTab, withReduxStateSync } from 'redux-state-sync'; - initMessageListener wrong
import initMessageListener from 'redux-state-sync';correctimport { initMessageListener } from 'redux-state-sync'; - withReduxStateSync wrong
const withReduxStateSync = require('redux-state-sync').withReduxStateSync;correctimport { withReduxStateSync } from 'redux-state-sync';
Quickstart
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