Redux vs Recoil: which should you use?
Tags: react, redux, recoil
Published: 2020-07-10 20:40:34

---
title: Redux vs Recoil: which should you use?
published: true
tags: react, redux, recoil
canonical_url: https://www.emgoto.com/redux-vs-recoil/
cover_image: https://www.emgoto.com/redux-vs-recoil-dev.png
---

[Recoil](https://github.com/facebookexperimental/Recoil), Facebook's experimental state management library for React, has been receiving a lot of hype. With [Redux](https://github.com/reduxjs/react-redux) being the most popular state management library, it's natural to ask the question - when does it make sense to use one over the other?

Let's take a look at some API differences between the two, plus some potential performance wins for Recoil.

## Redux Stores vs Recoil Atoms
In Redux, we have the concept of a centralised **store** where all the data for our app lives. 

In a simple to-do list example, your store would look something like this:

```js
{
    listName: 'My cool to-do list',
    tasks: {
        '1': {
            name: 'My first task',
        }
    }
}
```

Recoil instead splits your state into individual **atoms**. You would have one atom for `listName`, and another for `tasks`. Here’s how you would create the atom for your tasks (from [the Recoil docs](https://recoiljs.org/docs/basic-tutorial/atoms)):

```js
const todoListState = atom({
    key: 'todoListState',
    default: [],
});
```

At [ReactEurope](https://youtu.be/_ISAA_Jt9kI), the creator of Recoil, Dave McCabe, also introduced the possibility of creating individual atoms for each of your items:

```js
export const itemWithId =
    memoize(id => atom({
        key: `item${id}`,
        default: {...},
    }));
```

This means we could break it down further, and create an individual atom for each task.

## Redux vs Recoil: Performance

McCabe mentioned [in a comment on HackerNews](https://news.ycombinator.com/item?id=23183177):

> "Well, I know that on one tool we saw a 20x or so speedup compared to using Redux. This is because Redux is O(n) in that it has to ask each connected component whether it needs to re-render, whereas we can be O(1)."

Recoil is O(1) because when you edit the data in an **atom**, only components subscribed to that atom will re-render. 

In our to-do list example, if we had 20 separate tasks, we would have 20 separate atoms. If we edited the fifth task, only the fifth task would need to re-render.

Redux _does_ allow you to achieve the same effect using selectors:

```js
// selector
const taskSelector = (id) => state.tasks[id];

// component code
const task = useSelector(taskSelector(id));
```

With Redux, the component will only need to re-render when the specific task re-renders - same as Recoil.

The caveat here is that each time _any_ part of the state changes, our `taskSelector` would have to re-calculate. 

> We can use optimisations like `createSelector` to reduce expensive calculations. However it will still need to check whether it _needs_ to re-calculate.

With these performance optimisations, Recoil makes sense for huge apps that need to render a lot of components. A regular app is probably going to perform just fine with Redux. I don’t think it’s worth switching to Recoil for the potential (maybe nonexistent) performance benefits.

## Redux vs Recoil vs Context

You might also be wondering - what about React Context? Do you need a state management library at all?

Using React Context does have some potential downsides when it comes to performance. Any changes to state will cause re-renders for components that are using that state.

I have a separate post on [React Context](https://www.emgoto.com/react-state-management/#the-problem-with-react-context/) that explains this issue, and provides a workaround library you can use called React Tracked.

## Redux vs Recoil: API

So performance might not be the reason you need to switch to Recoil, but we can also compare the API of both libraries.

I'll be comparing [Redux Toolkit](https://redux-toolkit.js.org/) with Recoil, to create a simple example that lets you change the value stored in a text box.

> 💡 **What is Redux Toolkit?** 
>
> Redux Toolkit is a helper library aimed to help you simplify how you use Redux. If you're interested in learning more, I have a separate post on [Getting started with Redux Toolkit](https://www.emgoto.com/redux-toolkit/).

### Redux state management example

{% codepen https://codepen.io/emgoto/pen/wvWLxyy %}

### Recoil state management example

{% codepen https://codepen.io/emgoto/pen/wvWLxLx %}

> I also have to-do list examples of both [Redux Toolkit](https://github.com/emgoto/react-state-comparison/tree/master/src/redux-toolkit) and [Recoil](https://github.com/emgoto/react-state-comparison/tree/master/src/recoil) and other libraries over at [react-state-comparison](https://github.com/emgoto/react-state-comparison).

### Redux vs Recoil: API differences

Comparing the differences in API between Redux and Recoil:

* Both libraries need you to wrap the entire app in a provider component
* Recoil lets you initialise a store using `atom()`. This also comes with a selector and dispatchable action built-in
* Redux lets you create a store using `createSlice()` together with `configureStore()`. This comes with actions and a reducer. You'll need to define a selector separately
* Redux also requires the `useDispatch` and `useSelector` hooks to be able to dispatch actions and use selectors

Redux definitely does have some additional boilerplate to get started!

## Conclusion
To summarise some of the differences between Redux and Recoil: 

* Even with Redux Toolkit, Redux is still more "boilerplatey" than Recoil
* Recoil may provide performance benefits, but only if your app is complex enough
* Recoil is still in an experimental phase, while Redux is an established library

Another thing to point out is that Redux provides middleware functionality, while [Recoil does not yet support it](https://github.com/facebookexperimental/Recoil/issues/236).

Recoil does have some nice-looking benefits - it is possibly more performant, and has slightly less boilerplate to get started. However, it is still worth keeping in mind that it is an experimental library. So there are some risks you will be taking on if you choose to use it for a large project.