reduce-reducers
Combine multiple Redux reducers into a single reducer, applied left to right over one slice of state.
Repository Health
Technical Analysis
reduce-reducers is a tiny, zero-dependency helper that folds several reducer functions into one composite reducer. Unlike Redux’s own combineReducers, which partitions state by key and hands each reducer its own isolated slice, reduce-reducers runs every reducer over the same state object in sequence, threading the output of one into the next. That makes it the go-to primitive for handling cross-cutting actions that need to touch multiple parts of a shared state tree.
The entire library is a single higher-order function that accepts an optional initial state followed by any number of reducers and returns a standard (state, action) => state reducer. It ships CommonJS and ES-module builds plus TypeScript declarations, and slots directly into any Redux store or bare reducer pipeline.
What You Get
- A single default-exported
reduceReducers(...reducers)function that returns a standard Redux-compatible reducer - Optional initial-state support as the first argument, returned when the reducer runs with undefined state
- Dual CommonJS and ES-module builds plus bundled TypeScript type declarations
- Pass-through of extra reducer arguments beyond
(state, action)for advanced composition patterns
Common Use Cases
- Handling a single action that must update several independent parts of a shared state tree
- Composing feature-specific reducers on top of a combineReducers-partitioned root reducer
- Layering cross-cutting reducer logic (e.g. reset, hydration) over existing reducers
Under The Hood
Architecture
The entire library is a single default-exported higher-order function in src/index.js. It inspects its first argument: if that value is not a function it is shifted off as the initialState, and the remaining variadic arguments become the reducer list. It throws a TypeError if the initial state is undefined (nudging callers toward null), then returns a closure with the standard (prevState, value, ...args) signature. Inside, when both prior state and value are undefined it short-circuits to the initial state; otherwise it runs reducers.reduce(...), feeding each reducer the accumulated state and throwing on any undefined reducer in the chain.
Tech Stack
Written in plain ES-module JavaScript with no runtime dependencies. The build uses Babel (babel-preset-env) to emit both a CommonJS build (lib/) and an ES-module build (es/), wired through the main, module, and types fields in package.json. Hand-written TypeScript declarations live in index.d.ts. Tests run on Jest and linting is handled by xo with Prettier.
Code Quality
Despite its size the package is properly tested: test/index.test.js covers initial-state return, undefined-state handling, the undefined-initial-state error, multi-reducer combination and chaining, and extra-argument pass-through. Error paths are explicit TypeErrors with descriptive messages, and the single-expression implementation is clean and readable with no dead code.
API Design
The public surface is one function with an intuitive variadic signature, so getting started requires no configuration or boilerplate — import it and pass reducers. The overloaded TypeScript declaration models both the with- and without-initial-state call forms. The README gives a concise runnable example plus an FAQ that contrasts it with combineReducers, making the mental model easy to acquire.
Used by 2 apps in this directory
Grafana
Monitoring · Analytics
The open-source observability platform that unifies metrics, logs, and traces from any data source into dynamic, queryable dashboards.
Kibana
Analytics · Monitoring
Your open source window into the Elastic Stack — query, visualize, and act on data stored in Elasticsearch with real-time dashboards, AI-assisted search, and automated alerting.