redux vs @reduxjs/toolkit vs mobx vs vuex vs redux-saga
State Management Libraries Comparison
3 Years
redux@reduxjs/toolkitmobxvuexredux-sagaSimilar Packages:
What's State Management Libraries?

State management libraries are essential tools in modern web development, particularly for applications with complex state that needs to be shared across multiple components. These libraries provide a structured way to manage, update, and synchronize application state, making it easier to build scalable and maintainable applications. They help in handling state changes in a predictable manner, often using concepts like actions, reducers, and stores. Popular state management libraries include Redux, MobX, and Vuex, each with its own approach and set of features.

Package Weekly Downloads Trend
Github Stars Ranking
Stat Detail
Package
Downloads
Stars
Size
Issues
Publish
License
redux14,724,010
61,332290 kB462 years agoMIT
@reduxjs/toolkit6,173,276
11,0736.84 MB2536 days agoMIT
mobx2,054,715
28,0344.33 MB786 months agoMIT
vuex1,429,168
28,428271 kB143-MIT
redux-saga1,147,279
22,512221 kB432 years agoMIT
Feature Comparison: redux vs @reduxjs/toolkit vs mobx vs vuex vs redux-saga

State Management Approach

  • redux:

    Redux uses a centralized store to manage application state, with state changes handled by pure functions called reducers. It promotes a clear and predictable state management pattern, making it easier to understand and maintain.

  • @reduxjs/toolkit:

    @reduxjs/toolkit follows a unidirectional data flow model, where state changes are triggered by actions dispatched to reducers. It enforces a clear separation of concerns, making state management predictable and easy to debug.

  • mobx:

    MobX employs a reactive programming model, where state changes automatically update the UI without the need for manual intervention. It allows for more dynamic and flexible state management, reducing the need for boilerplate code.

  • vuex:

    Vuex provides a centralized store for Vue.js applications, with a clear structure for managing state, mutations, and actions. It integrates seamlessly with Vue's reactivity system, making state management intuitive and efficient.

  • redux-saga:

    redux-saga is an extension of Redux that focuses on managing side effects in a more structured way. It uses sagas (generator functions) to handle asynchronous actions, allowing for better control and organization of complex side effect logic.

Boilerplate Code

  • redux:

    Redux is known for its boilerplate, requiring developers to define actions, reducers, and store setup explicitly, which can be time-consuming and verbose.

  • @reduxjs/toolkit:

    @reduxjs/toolkit significantly reduces boilerplate code compared to traditional Redux by providing a set of tools and best practices that streamline the process of setting up and managing state.

  • mobx:

    MobX minimizes boilerplate code by allowing developers to define state and reactions in a more natural and intuitive way, without the need for extensive configuration or setup.

  • vuex:

    Vuex requires some boilerplate for setting up the store, mutations, and actions, but it is relatively straightforward and well-structured, especially for Vue.js applications.

  • redux-saga:

    redux-saga introduces additional boilerplate for defining sagas and managing side effects, but it provides a more organized and scalable way to handle complex asynchronous logic.

Learning Curve

  • redux:

    Redux has a steeper learning curve due to its concepts of actions, reducers, and middleware. However, once understood, it provides a solid foundation for managing state in JavaScript applications.

  • @reduxjs/toolkit:

    @reduxjs/toolkit has a gentler learning curve compared to traditional Redux, thanks to its simplified API and clear documentation. It is designed to help developers quickly understand and implement state management best practices.

  • mobx:

    MobX is relatively easy to learn, especially for those familiar with reactive programming concepts. Its intuitive API and minimal configuration make it accessible for developers of all skill levels.

  • vuex:

    Vuex is easy to learn for developers already familiar with Vue.js, as it follows similar principles and integrates seamlessly with the Vue ecosystem.

  • redux-saga:

    redux-saga can be challenging to learn, particularly for developers unfamiliar with generator functions and asynchronous programming. It requires a good understanding of Redux to use effectively.

Integration with Frameworks

  • redux:

    Redux is framework-agnostic but is most commonly used with React. It can be integrated with any JavaScript framework or library that supports a unidirectional data flow.

  • @reduxjs/toolkit:

    @reduxjs/toolkit integrates seamlessly with React and other JavaScript frameworks, providing a flexible and scalable solution for managing state in component-based architectures.

  • mobx:

    MobX works well with any JavaScript framework, including React, Vue, and Angular. Its reactive nature makes it particularly compatible with component-based architectures.

  • vuex:

    Vuex is specifically designed for Vue.js applications, providing a state management solution that leverages Vue's reactivity system and integrates seamlessly with Vue components.

  • redux-saga:

    redux-saga is designed to work with Redux, making it a natural fit for React applications that require advanced side effect management.

Ease of Use: Code Examples

  • redux:

    Simple counter example with Redux

    import { createStore } from 'redux';
    
    const initialState = { count: 0 };
    
    const counterReducer = (state = initialState, action) => {
      switch (action.type) {
        case 'INCREMENT':
          return { count: state.count + 1 };
        case 'DECREMENT':
          return { count: state.count - 1 };
        default:
          return state;
      }
    };
    
    const store = createStore(counterReducer);
    
    store.subscribe(() => console.log(store.getState()));
    store.dispatch({ type: 'INCREMENT' });
    store.dispatch({ type: 'DECREMENT' });
    
  • @reduxjs/toolkit:

    Simple counter example with @reduxjs/toolkit

    import { createSlice, configureStore } from '@reduxjs/toolkit';
    
    const counterSlice = createSlice({
      name: 'counter',
      initialState: 0,
      reducers: {
        increment: (state) => state + 1,
        decrement: (state) => state - 1,
      },
    });
    
    const store = configureStore({
      reducer: { counter: counterSlice.reducer },
    });
    
    store.subscribe(() => console.log(store.getState()));
    store.dispatch(counterSlice.actions.increment());
    store.dispatch(counterSlice.actions.decrement());
    
  • mobx:

    Simple counter example with MobX

    import { makeAutoObservable } from 'mobx';
    import { observer } from 'mobx-react';
    import React from 'react';
    
    class Counter {
      count = 0;
    
      constructor() {
        makeAutoObservable(this);
      }
    
      increment() {
        this.count++;
      }
    
      decrement() {
        this.count--;
      }
    }
    
    const counter = new Counter();
    
    const CounterComponent = observer(() => (
      <div>
        <h1>{counter.count}</h1>
        <button onClick={() => counter.increment()}>Increment</button>
        <button onClick={() => counter.decrement()}>Decrement</button>
      </div>
    ));
    
    export default function App() {
      return <CounterComponent />;
    }
    
  • vuex:

    Simple counter example with Vuex

    import Vue from 'vue';
    import Vuex from 'vuex';
    
    Vue.use(Vuex);
    
    const store = new Vuex.Store({
      state: { count: 0 },
      mutations: {
        increment(state) {
          state.count++;
        },
        decrement(state) {
          state.count--;
        },
      },
    });
    
    store.subscribe(() => console.log(store.state.count));
    store.commit('increment');
    store.commit('decrement');
    
  • redux-saga:

    Simple counter example with redux-saga

    import { createStore, applyMiddleware } from 'redux';
    import createSagaMiddleware from 'redux-saga';
    import { takeEvery, put } from 'redux-saga/effects';
    
    const initialState = { count: 0 };
    
    const counterReducer = (state = initialState, action) => {
      switch (action.type) {
        case 'INCREMENT':
          return { count: state.count + 1 };
        case 'DECREMENT':
          return { count: state.count - 1 };
        default:
          return state;
      }
    };
    
    function* incrementAsync() {
      yield put({ type: 'INCREMENT' });
    }
    
    function* watchIncrement() {
      yield takeEvery('INCREMENT_ASYNC', incrementAsync);
    }
    
    const sagaMiddleware = createSagaMiddleware();
    const store = createStore(counterReducer, applyMiddleware(sagaMiddleware));
    sagaMiddleware.run(watchIncrement);
    
    store.subscribe(() => console.log(store.getState()));
    store.dispatch({ type: 'INCREMENT_ASYNC' });
    
How to Choose: redux vs @reduxjs/toolkit vs mobx vs vuex vs redux-saga
  • redux:

    Opt for Redux if you need a predictable state container for JavaScript applications. It is particularly useful for large applications with complex state logic, providing a clear structure for managing state changes through actions and reducers.

  • @reduxjs/toolkit:

    Choose @reduxjs/toolkit if you are building a React application and need a robust, scalable state management solution with a focus on best practices and performance. It simplifies Redux setup and encourages a more efficient way of writing Redux logic.

  • mobx:

    Select MobX if you prefer a more reactive and less boilerplate-heavy approach to state management. It is ideal for applications where you want to manage state in a more intuitive way, using observables and reactions, which can lead to simpler and more maintainable code.

  • vuex:

    Select Vuex if you are developing a Vue.js application and need a state management solution that integrates seamlessly with the Vue ecosystem. It provides a centralized store for all components in an application, making state management more predictable and easier to debug.

  • redux-saga:

    Choose redux-saga if your application requires advanced handling of side effects, such as asynchronous actions, API calls, or complex business logic. It uses generator functions to manage side effects in a more organized and testable way, making it suitable for applications with intricate asynchronous workflows.

README for redux

Redux Logo

Redux is a predictable state container for JavaScript apps.

It helps you write applications that behave consistently, run in different environments (client, server, and native), and are easy to test. On top of that, it provides a great developer experience, such as live code editing combined with a time traveling debugger.

You can use Redux together with React, or with any other view library. The Redux core is tiny (2kB, including dependencies), and has a rich ecosystem of addons.

Redux Toolkit is our official recommended approach for writing Redux logic. It wraps around the Redux core, and contains packages and functions that we think are essential for building a Redux app. Redux Toolkit builds in our suggested best practices, simplifies most Redux tasks, prevents common mistakes, and makes it easier to write Redux applications.

GitHub Workflow Status npm version npm downloads redux channel on discord

Installation

Create a React Redux App

The recommended way to start new apps with React and Redux Toolkit is by using our official Redux Toolkit + TS template for Vite, or by creating a new Next.js project using Next's with-redux template.

Both of these already have Redux Toolkit and React-Redux configured appropriately for that build tool, and come with a small example app that demonstrates how to use several of Redux Toolkit's features.

# Vite with our Redux+TS template
# (using the `degit` tool to clone and extract the template)
npx degit reduxjs/redux-templates/packages/vite-template-redux my-app

# Next.js using the `with-redux` template
npx create-next-app --example with-redux my-app

We do not currently have official React Native templates, but recommend these templates for standard React Native and for Expo:

  • https://github.com/rahsheen/react-native-template-redux-typescript
  • https://github.com/rahsheen/expo-template-redux-typescript
npm install @reduxjs/toolkit react-redux

For the Redux core library by itself:

npm install redux

For more details, see the Installation docs page.

Documentation

The Redux core docs are located at https://redux.js.org, and include the full Redux tutorials, as well usage guides on general Redux patterns:

The Redux Toolkit docs are available at https://redux-toolkit.js.org, including API references and usage guides for all of the APIs included in Redux Toolkit.

Learn Redux

Redux Essentials Tutorial

The Redux Essentials tutorial is a "top-down" tutorial that teaches "how to use Redux the right way", using our latest recommended APIs and best practices. We recommend starting there.

Redux Fundamentals Tutorial

The Redux Fundamentals tutorial is a "bottom-up" tutorial that teaches "how Redux works" from first principles and without any abstractions, and why standard Redux usage patterns exist.

Help and Discussion

The #redux channel of the Reactiflux Discord community is our official resource for all questions related to learning and using Redux. Reactiflux is a great place to hang out, ask questions, and learn - please come and join us there!

Before Proceeding Further

Redux is a valuable tool for organizing your state, but you should also consider whether it's appropriate for your situation. Please don't use Redux just because someone said you should - instead, please take some time to understand the potential benefits and tradeoffs of using it.

Here are some suggestions on when it makes sense to use Redux:

  • You have reasonable amounts of data changing over time
  • You need a single source of truth for your state
  • You find that keeping all your state in a top-level component is no longer sufficient

Yes, these guidelines are subjective and vague, but this is for a good reason. The point at which you should integrate Redux into your application is different for every user and different for every application.

For more thoughts on how Redux is meant to be used, please see:

Basic Example

The whole global state of your app is stored in an object tree inside a single store. The only way to change the state tree is to create an action, an object describing what happened, and dispatch it to the store. To specify how state gets updated in response to an action, you write pure reducer functions that calculate a new state based on the old state and the action.

Redux Toolkit simplifies the process of writing Redux logic and setting up the store. With Redux Toolkit, the basic app logic looks like:

import { createSlice, configureStore } from '@reduxjs/toolkit'

const counterSlice = createSlice({
  name: 'counter',
  initialState: {
    value: 0
  },
  reducers: {
    incremented: state => {
      // Redux Toolkit allows us to write "mutating" logic in reducers. It
      // doesn't actually mutate the state because it uses the Immer library,
      // which detects changes to a "draft state" and produces a brand new
      // immutable state based off those changes
      state.value += 1
    },
    decremented: state => {
      state.value -= 1
    }
  }
})

export const { incremented, decremented } = counterSlice.actions

const store = configureStore({
  reducer: counterSlice.reducer
})

// Can still subscribe to the store
store.subscribe(() => console.log(store.getState()))

// Still pass action objects to `dispatch`, but they're created for us
store.dispatch(incremented())
// {value: 1}
store.dispatch(incremented())
// {value: 2}
store.dispatch(decremented())
// {value: 1}

Redux Toolkit allows us to write shorter logic that's easier to read, while still following the original core Redux behavior and data flow.

Logo

You can find the official logo on GitHub.

Change Log

This project adheres to Semantic Versioning. Every release, along with the migration instructions, is documented on the GitHub Releases page.

License

MIT