Javascript

Redux - multiple stores why not

25 September 2026 · 10 min read

Redux - multiple stores why not

Managing application state is a crucial aspect of front-end development, especially as applications grow in complexity. Redux has long been a popular choice for state management in JavaScript applications, offering a predictable and centralized way to handle data flow. However, a common question arises as developers delve deeper: should we use multiple Redux stores? While seemingly convenient for separating concerns, the approach of employing multiple stores often introduces more complexity than it solves. This article delves into the reasons why using multiple Redux stores is generally discouraged, exploring the benefits of sticking with a single store and outlining strategies for effective state management within a unified Redux architecture.

Understanding the Single Store Principle

Redux’s core principle revolves around maintaining a single source of truth for your application’s state. This single store acts as a central repository, holding all the data necessary for the UI to render and respond to user interactions. This centralized approach significantly simplifies debugging and predictability. By having all state changes flow through a single store, developers gain a clear and comprehensive overview of how data is being modified, reducing the risk of unexpected behavior.

Furthermore, using a single store promotes better maintainability. With all state logic concentrated in one place, it’s easier to reason about the codebase, track down bugs, and implement changes without inadvertently affecting other parts of the application. This unified structure also simplifies tasks like state serialization and hydration, contributing to a smoother development process.

Imagine a complex application with features like user authentication, product listings, and shopping cart functionality. With a single store, these distinct features can still maintain their own slices of state within the global object, ensuring modularity while still benefiting from the centralized structure.

The Pitfalls of Multiple Stores

While the idea of separating concerns through multiple stores might seem attractive at first glance, it often introduces a host of challenges. One major drawback is the increased complexity in managing data flow. Synchronizing state changes across multiple stores can become a nightmare, leading to unpredictable behavior and difficult-to-debug issues. This complexity also makes testing more cumbersome, as individual stores need to be mocked or synchronized for accurate test results.

Moreover, using multiple stores negates one of Redux’s primary benefits: a clear and unified view of the application’s state. Debugging becomes significantly harder as developers have to juggle multiple sources of truth, making it challenging to track down the root cause of issues. This fragmented state management approach also complicates tasks like time-travel debugging and state persistence.

A common misconception is that multiple stores improve performance. In reality, the overhead introduced by managing the interaction and synchronization between stores often outweighs any potential performance gains. A well-structured single store, with proper selectors and optimized reducers, can handle even complex state structures efficiently.

Effective State Management with a Single Store

Managing a complex application’s state within a single Redux store is entirely feasible and often preferable. Leveraging techniques like combining reducers, utilizing selectors for data retrieval, and structuring the store with clear hierarchies allows for both a unified and organized approach. This structure maintains the benefits of a single store while enabling modularity and separation of concerns within the state object itself.

Combining reducers is a powerful tool for organizing state logic. By breaking down the overall state into smaller, manageable reducers, each responsible for a specific domain or feature, developers can maintain modularity within the single store paradigm. These smaller reducers are then combined to form the root reducer, which manages the entire application state.

Selectors play a crucial role in efficiently retrieving data from the Redux store. By providing memoized functions to extract specific pieces of information from the state, selectors prevent unnecessary re-renders and optimize performance. They also provide a clear and consistent way to access data within components, simplifying component logic and improving code readability.

  • Combining reducers for modularity.
  • Using selectors for efficient data retrieval.

Advanced Techniques for Scaling State Management

As applications grow increasingly complex, even a single store might benefit from additional tools and techniques for optimized state management. For very large applications, consider exploring libraries like Redux Toolkit which simplifies Redux setup and promotes best practices. Redux Toolkit provides utilities for creating reducers, actions, and thunks with less boilerplate, streamlining the development process and making state management more manageable. It also integrates seamlessly with other Redux ecosystem libraries.

Another helpful technique is utilizing normalized state structures, particularly when dealing with large collections of data. Normalization involves storing data in a flat, denormalized format, reducing redundancy and improving performance. This approach is especially useful for managing relational data and simplifies updates and lookups within the state.

For handling asynchronous operations, Redux Thunk or Redux Saga provide powerful mechanisms for managing side effects and complex data flows. These middleware solutions allow developers to dispatch functions that perform asynchronous actions, such as API calls, and update the Redux store based on the results, while keeping the core Redux logic pure and predictable.

  1. Explore Redux Toolkit for simplified setup and best practices.
  2. Utilize normalized state structures for large data sets.
  3. Leverage Redux Thunk or Redux Saga for asynchronous operations.

Infographic Placeholder: Visualizing the single store architecture and its benefits.

“Redux Toolkit drastically simplifies common Redux tasks and makes it easier to scale your state management as your application grows.” - Mark Erikson, Redux maintainer.

Featured Snippet Optimized Paragraph: Why should I avoid multiple Redux stores? Multiple Redux stores complicate data flow, hinder debugging, and often decrease performance, contradicting Redux’s core principles. A single store with proper structuring provides a more manageable, scalable, and predictable solution for state management.

FAQ

Q: When might multiple Redux stores seem beneficial? A: In extremely complex applications with entirely isolated modules, separate stores might seem appealing. However, even in these scenarios, a single store with proper organization usually provides a more robust and maintainable solution.

By focusing on a well-structured single store and utilizing the available tools and techniques within the Redux ecosystem, developers can create robust, scalable, and maintainable state management solutions for even the most complex applications. Learn more about advanced Redux patterns. This unified approach not only simplifies development but also enhances the overall performance and predictability of your application. Consider implementing these best practices in your next project to experience the true power and efficiency of centralized state management with Redux. Explore resources like the official Redux documentation and community forums to further deepen your understanding and connect with other developers using Redux. You can also find more information on state management patterns at Example.com and best practices for Redux at Example.com/redux.

  • Redux Toolkit
  • Normalized State
  • State Management
  • Single Source of Truth
  • Asynchronous Actions
  • Reducers
  • Selectors

Question & Answer :
As a note: I’ve read the docs for Redux (Baobab, too), and I’ve done a fair share of Googling & testing.

Why is it so strongly suggested that a Redux app have only one store?

I understand the pros/cons of a single-store setup vs a multiple store setup (There are many Q&A on SO on this subject).

IMO, this architectural decision belongs to the app developers based on their projects’ needs. So why is it so strongly suggested for Redux, almost to the point of sounding mandatory (though nothing is stopping us from making multiple stores)?

EDIT: feedback after converting to single-store

After a few months working with redux on what many would consider a complex SPA, I can say that the single store structure has been a pure delight to work with.

A few points that might help others understand why single store vs many store is a moot question in many, many use-cases:

  • it’s reliable: we use selectors to dig through the app state and obtain context-relevant information. We know that all the needed data is in a single store. It avoids all questioning as to where state issues could be.
  • it’s fast: our store currently has close to 100 reducers, if not more. Even at that count, only a handful of reducers process data on any given dispatch, the others just return the previous state. The argument that a huge/complex store (nbr of reducers) is slow is pretty much moot. At least we’ve not seen any performance issues coming from there.
  • debugging friendly: while this is a most convincing argument to use redux as a whole, it also goes for single store vs multiple store. When building an app you’re bound to have state errors in the process (programmer mistakes), it’s normal. The PITA is when those errors take hours to debug. Thanks to the single store (and redux-logger) we’ve never spent more than a few minutes on any given state issue.

a few pointers

The true challenge in building your redux store is when deciding how to structure it. Firstly, because changing structure down the road is just a major pain. Secondly, because it largely determines how you’ll be using, and querying your app data for any process. There are many suggestions on how to structure a store. In our case we found the following to be ideal:

{ apis: { // data from various services api1: {}, api2: {}, ... }, components: {} // UI state data for each widget, component, you name it session: {} // session-specific information } 

Hopefully this feedback will help others.

EDIT 2 - helpful store tools

For those of you who have been wondering how to “easily” manage a single store, which can quickly get complex. There are a tools that help isolate the structural dependencies/logic of your store.

There is Normalizr which normalizes your data based on a schema. It then provides an interface to work with your data and fetch other parts of your data by id, much like a Dictionary.

Not knowing Normalizr at the time, I built something along the same lines. relational-json takes a schema, and returns a Table-based interface (a little like a database). The advantage of relational-json is that your data structure dynamically references other parts of your data (essentially, you can traverse your data in any direction, just like normal JS objects). It’s not as mature as Normalizr, but I’ve been using it successfully in production for a few months now.

There are edge cases when you might use multiple stores (e.g. if you have performance problems with updating lists of thousands of items that are on screen at the same time many times per second). That said it’s an exception and in most apps you never need more than a single store.

Why do we stress this in the docs? Because most people coming from Flux background will assume multiple stores is the solution to making update code modular. However Redux has a different solution for this: reducer composition.

Having multiple reducers that are further split into a reducer tree is how you keep updates modular in Redux. If you don’t recognize this and go for multiple stores without fully understanding reducer composition first, you will miss many benefits of Redux single store architecture:

  • Using reducer composition makes it easy to implement “dependent updates” a la waitFor in Flux by writing a reducer manually calling other reducers with additional information and in a specific order.
  • With a single store, it’s very easy to persist, hydrate, and read the state. Server rendering and data prefetching is trivial because there is just one data storage that needs to be filled and rehydrated on the client, and JSON can describe its contents without worrying about store’s ID or name.
  • A single store makes Redux DevTools time travel features possible. It also makes community extensions like redux-undo or redux-optimist easy because they operate on the reducer level. Such “reducer enhancers” can’t be written for stores.
  • A single store guarantees that the subscriptions are called only after the dispatch has been processed. That is, by the time listeners are notified, the state has been fully updated. With many stores, there are no such guarantees. This is one of the reasons Flux needs the waitFor crutch. With a single store, this is not a problem you see in the first place.
  • Above all, multiple stores are unnecessary in Redux (except for performance edge cases which you are supposed to profile first anyway). We make it an important point in the docs so you are encouraged to learn reducer composition and other Redux patterns instead of using Redux as if it was Flux, and losing its benefits.