Redux Replaceable Middleware
raw JSON →Redux Replaceable Middleware is a utility that provides a mechanism to dynamically replace active Redux middleware instances at runtime. Published approximately 8 years ago, its current stable version is 1.1.0, and it appears to be abandoned, with no recent updates or active maintenance. This package was designed for earlier versions of Redux (specifically peer-depending on Redux v2, v3, or v4), and its core differentiation lies in enabling modification of the middleware chain after the Redux store has been created. In contrast, standard Redux practice involves defining the middleware chain once during store creation. Modern Redux applications, especially those using Redux Toolkit, typically manage asynchronous logic and side effects through patterns like Redux Thunk, Redux Saga, or Redux Toolkit's `createAsyncThunk` and listeners, rather than dynamic middleware replacement.
Common errors
error TypeError: ReplaceableMiddleware is not a function ↓
const replaceableMiddleware = ReplaceableMiddleware(); error Error [ERR_REQUIRE_ESM]: require() of ES Module ... Not supported in ES module scope ↓
import() statement if supported, though the package itself does not provide ESM exports. It's generally recommended to use actively maintained alternatives that support modern module systems. error TypeError: Cannot read properties of undefined (reading 'dispatch') ↓
Redux.applyMiddleware during store creation. The options object is populated by Redux and available within the middleware's replaceBy function or through replaceableMiddleware.options after the store is created. Warnings
breaking This package is designed for Redux versions 2.x, 3.x, and 4.x. It may not be compatible with Redux v5 or later, especially when used with Redux Toolkit's `configureStore`, which has different middleware handling. ↓
gotcha This package is CommonJS-only and does not provide ES module exports. Attempting to use `import` statements will result in runtime errors in environments that enforce ESM. ↓
deprecated The package is effectively abandoned, with its last update being 8 years ago. It lacks maintenance, security updates, and compatibility with modern JavaScript features or contemporary Redux practices (e.g., Redux Toolkit, TypeScript). ↓
gotcha This package does not ship with TypeScript type definitions. Using it in a TypeScript project will require manually declaring types or ignoring type errors, reducing type safety. ↓
Install
npm install redux-replaceable-middleware yarn add redux-replaceable-middleware pnpm add redux-replaceable-middleware Imports
- ReplaceableMiddleware wrong
import ReplaceableMiddleware from 'redux-replaceable-middleware';correctconst ReplaceableMiddleware = require('redux-replaceable-middleware'); - ReplaceableMiddleware factory call
const myReplaceableMiddleware = ReplaceableMiddleware();
Quickstart
const Redux = require('redux');
const ReplaceableMiddleware = require('redux-replaceable-middleware');
// A dummy reducer
const reducer = (state = { value: 0 }, action) => {
switch (action.type) {
case 'INCREMENT':
return { ...state, value: state.value + 1 };
case 'DECREMENT':
return { ...state, value: state.value - 1 };
default:
return state;
}
};
// Initial middleware (logs actions)
const loggingMiddleware = store => next => action => {
console.log('OLD Middleware: Dispatching', action.type, 'payload:', action.payload);
const result = next(action);
console.log('OLD Middleware: Next state', store.getState());
return result;
};
// Create the replaceable middleware instance
const replaceableMiddleware = ReplaceableMiddleware(loggingMiddleware);
// Create the store with the replaceable middleware
const store = Redux.createStore(
reducer,
Redux.applyMiddleware(replaceableMiddleware)
);
console.log('Initial state:', store.getState());
store.dispatch({ type: 'INCREMENT' });
// New middleware (adds a prefix to action type)
const newMiddleware = store => next => action => {
console.log('NEW Middleware: Pre-processing action', action.type);
const newAction = { ...action, type: `PREFIX_${action.type}` };
const result = next(newAction);
console.log('NEW Middleware: Post-processing action', newAction.type);
return result;
};
console.log('\nReplacing middleware in 1 second...');
setTimeout(() => {
replaceableMiddleware.replaceBy(newMiddleware);
console.log('Middleware replaced! Dispatching again...');
store.dispatch({ type: 'DECREMENT' });
store.dispatch({ type: 'INCREMENT' });
console.log('Final state:', store.getState());
}, 1000);