Redux Hub Middleware

raw JSON →
1.0.4 verified Thu Apr 23 auth: no javascript maintenance

This Redux middleware addresses the challenge of managing multiple, isolated Redux stores within a single application, a common pattern in large React/Redux projects with distinct sub-applications. It provides a mechanism, a 'hub', to re-dispatch actions across all connected stores, effectively synchronizing state changes that originate from any single store. The current stable version is 1.0.4. While the package hasn't seen recent major updates since its initial releases, its core functionality remains relevant for specific multi-store architectures. Its key differentiator is providing a simple, explicit hub for action propagation without merging states or requiring complex global state management solutions, allowing individual stores to retain their isolation while enabling cross-store communication.

error TypeError: hub.connect is not a function
cause The `createReduxHub()` function was not called, or its return value was not assigned to `hub` (e.g., `const hub = createReduxHub();`). The `connect` and `middleware` properties are on the object returned by the function call.
fix
Ensure you call createReduxHub() to get the hub instance: const hub = createReduxHub();
error Store state not synchronizing across connected stores
cause Either the `hub.middleware` was not applied to one or more stores, or `hub.connect(store)` was not called for all desired stores.
fix
Verify that applyMiddleware(hub.middleware) is used when creating each store, and that hub.connect(store) is explicitly called for every store intended to participate in the hub.
error Warning: Middleware for RTK-Query API at reducerPath "..." has not been added to the store.
cause When using Redux Toolkit's `configureStore`, if you provide a custom `middleware` array, you must explicitly include `getDefaultMiddleware()` to retain RTK's built-in middleware (like thunk and RTK Query's middleware).
fix
Modify your configureStore call to include getDefaultMiddleware() when adding redux-hub-middleware: middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(hub.middleware).
gotcha Actions dispatched through the hub are re-dispatched to *all* connected stores. Ensure your reducers are designed to handle actions appropriately, or you may experience unintended state changes across stores that should remain isolated from certain actions.
fix Implement robust action type checking or specific reducer logic to ignore irrelevant actions in certain stores, or consider using action prefixes/suffixes for store-specific actions.
gotcha This package uses the `createStore` and `applyMiddleware` functions from the core `redux` library, which are considered legacy in modern Redux development. Redux Toolkit's `configureStore` is the recommended approach. While functionally compatible, integrating `redux-hub-middleware` with `configureStore` requires careful manual middleware configuration.
fix When using Redux Toolkit, pass `hub.middleware` directly into the `middleware` array of `configureStore` (e.g., `configureStore({ reducer, middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(hub.middleware) })`).
gotcha Performance may be impacted in applications with a very large number of connected stores or extremely high-frequency action dispatches, as each action is processed and re-dispatched potentially multiple times across the hub.
fix Monitor performance closely. If bottlenecks occur, evaluate if all actions truly need to be propagated to all stores. Consider alternative patterns like selective store listeners or a more granular messaging system for complex scenarios.
breaking Redux v5.0.0 and Redux Toolkit v2.0.0 introduced changes to middleware typing, where `action` and `next` parameters are typed as `unknown`. Middleware written against older Redux types might require updates to explicitly type-guard actions. While `redux-hub-middleware` itself is unlikely to break, custom middleware used in conjunction with it might.
fix If experiencing TypeScript errors with custom middleware, implement type guards (e.g., `isAction(action)`) before accessing properties of the `action` object. The `redux-hub-middleware` library itself may or may not provide updated types for Redux v5 compatibility.
npm install redux-hub-middleware
yarn add redux-hub-middleware
pnpm add redux-hub-middleware

Demonstrates creating two isolated Redux stores, connecting them via `redux-hub-middleware`, and showing how actions dispatched on one store propagate to all connected stores.

import { createStore, applyMiddleware } from 'redux';
import createReduxHub from 'redux-hub-middleware';

// Create a Redux Hub instance
const hub = createReduxHub();

// Define two simple reducers for separate stores
function reducer1(state = 'Store 1 initial state', action) {
  if (action.type === 'CHANGE_VALUE') {
    return action.payload;
  }
  return state;
}

function reducer2(state = 'Store 2 initial state', action) {
  if (action.type === 'CHANGE_VALUE') {
    return action.payload;
  }
  return state;
}

// Create two Redux stores, each applying the hub's middleware
const store1 = createStore(reducer1, applyMiddleware(hub.middleware));
const store2 = createStore(reducer2, applyMiddleware(hub.middleware));

// Connect both stores to the Redux Hub
hub.connect(store1);
hub.connect(store2);

console.log('Initial State Store 1:', store1.getState());
console.log('Initial State Store 2:', store2.getState());

// Dispatch an action on store1
store1.dispatch({ type: 'CHANGE_VALUE', payload: 'Value changed by Store 1' });

console.log('After Store 1 dispatch:');
console.log('Store 1:', store1.getState()); // Should reflect change
console.log('Store 2:', store2.getState()); // Should also reflect change due to hub

// Dispatch an action on store2
store2.dispatch({ type: 'CHANGE_VALUE', payload: 'Value changed by Store 2' });

console.log('After Store 2 dispatch:');
console.log('Store 1:', store1.getState()); // Should reflect change
console.log('Store 2:', store2.getState()); // Should also reflect change