# Easy Peasy: Redux-style state for React without the boilerplate

> Easy Peasy wraps Redux in a store-and-model API built for React hooks. The v7 line is in beta, the v6 line is the current stable release, and the project still ships under the MIT licence.

**ctrlplusb/easy-peasy** — Vegetarian friendly state for React

- Repository: https://github.com/ctrlplusb/easy-peasy
- Website: https://easy-peasy.dev
- Stars: 5,040 · Forks: 185
- Language: JavaScript
- License: MIT
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/ctrlplusb-easy-peasy

## The problem easy-peasy removes from a Redux codebase

Redux gives you architectural guarantees and a large ecosystem, but the plain API asks for action types, action creators, reducers, and a provider wiring step before a single value moves. Easy Peasy keeps the Redux runtime underneath and replaces that surface with a single object. The README calls it "an abstraction of Redux, providing a reimagined API that focuses on developer experience".

That is the whole pitch. The audience is a React team that already accepts Redux's model but resents the ceremony, or a smaller team that wants one dependency instead of a hand-assembled stack of reducer helpers, selectors and middleware glue. The README claims zero configuration, no boilerplate, a hooks-based API, computed properties, reactive actions, middleware support, persistence, DevTools, and global, context or local stores.

Scope matters here. Easy Peasy does not replace Redux's mental model, it renames and compresses it. If you dislike the idea of a central store, this library will not help you; it will give you the same central store with shorter file names.

## How the store, actions and hooks fit together

A store is created from a plain object. State lives as ordinary values on that object, and mutations are declared as actions. The README's example puts a todos array and an addTodo action side by side, then mutates the array with state.todos.push(payload). The push is the interesting part: the topics list includes immer, so the mutation syntax is the surface and the underlying update is immutable. You write imperative code and the library produces the immutable transition.

The data flow is the standard one. createStore builds the store, StoreProvider puts it on React context, and components read from it with hooks. useStoreState takes a selector function over state, useStoreActions takes a selector over the action map. Both are called with a function rather than a key path, so TypeScript can infer the shape of what you select.

Several capabilities are declared in the README but not shown in it. Computed properties, reactive actions, state persistence and the built-in testing utilities all appear in the feature list without an example. The official website is where the README sends you for "tutorials, docs, recipes, and more", so treat the README as an index rather than a manual. The repository layout backs this up: there is a website/ directory, a tests/ directory, and a set of examples covering simple-todo, kanban, reduxtagram, nextjs-ssr, nextjs-app-router, nextjs-todo, react-native-todo and v7-concurrent.

## Installing easy-peasy and reading state in a component

The README documents a single dependency install. Because v7 is in beta, the README states it is published under the beta dist-tag, and the latest tag will move to v7 once the stable release ships. That distinction decides which version you get, so be deliberate about it.

```bash
npm install easy-peasy@beta
```

For the current stable line, the README points at the v6 docs site rather than giving a separate install command, and the v6 line is what the latest tag currently resolves to. The package declares an engine requirement in package.json, so check your runtime before installing.

```json
"engines": {
  "node": ">=18"
}
```

Next, create a store. This is the README's own example, with a state array and one action that mutates it.

```javascript
const store = createStore({
  todos: ['Create store', 'Wrap application', 'Use store'],

  addTodo: action((state, payload) => {
    state.todos.push(payload);
  }),
});
```

Wrap the tree so the hooks can find the store. Everything below StoreProvider can call the hooks; anything outside it cannot.

```javascript
function App() {
  return (
    <StoreProvider store={store}>
      <TodoList />
    </StoreProvider>
  );
}
```

Finally, read and dispatch from a component. The selector functions receive the whole state and the whole action map respectively, and the component re-renders when the selected value changes.

```javascript
function TodoList() {
  const todos = useStoreState((state) => state.todos);
  const addTodo = useStoreActions((actions) => actions.addTodo);
  return (
    <div>
      {todos.map((todo, idx) => (
        <div key={idx}>{todo}</div>
      ))}
      <AddTodo onAdd={addTodo} />
    </div>
  );
}
```

That is the entire first run: install, createStore, StoreProvider, two hooks. The README's examples/ folder has a simple-todo project if you want a working reference rather than a snippet.

## The beta tag is the first thing to check before you commit

The README is explicit that v7 is in beta and that "APIs may shift in response to feedback before the stable release". The package.json in the repository carries version 7.0.0-beta.2. So the repository's default branch is not describing the version most installs will receive.

That split has a practical consequence. A team that runs npm install easy-peasy without the beta tag and a team that runs npm install easy-peasy@beta are on different lines, with different documentation sites. The README links the v6 to v7 upgrade guide and a separate v6 docs site, which means two documentation surfaces exist at once and you need to know which one applies to your lockfile.

The second limitation is conceptual rather than technical. The mutation syntax is a deliberate convenience, and it hides immutability. A developer who does not know that state.todos.push is intercepted can be surprised by which parts of a model are safe to touch directly and which are not. The README does not explain the interception; it just shows the syntax. If your team already struggles to reason about where state changes originate, this API makes the change look smaller than it is.

Third, the README lists persistence, computed properties and testing utilities as features without documenting them. That is not a reason to avoid the library, but it does mean the README alone is not enough to evaluate those claims. You will be reading easy-peasy.dev.

## easy-peasy against plain Redux and a reducer toolkit

The obvious alternative is Redux itself, with or without a reducer helper library. The difference is where the abstraction sits. Plain Redux keeps actions, reducers and the store as distinct concepts and expects you to wire them; easy-peasy collapses them into one object where a function on the model is both the action and its reducer. If you want to see the action type and the reducer transition as separate artefacts, easy-peasy is working against you.

The second alternative is a selector-and-atom library, where state is split into independent units rather than one store object. Easy Peasy keeps the single store, so anything you gain from isolated units, including per-unit subscriptions and a smaller blast radius when one unit changes, is not on offer. The README's feature list includes "Global, context, or local stores", which softens this, but the default shape is still one store.

Where easy-peasy is genuinely different from a bare Redux setup is the ecosystem claim. The README states it lets you "leverage the strong architectural guarantees and extensive eco-system that Redux has to offer", and lists Redux middleware support and Redux Dev Tools as features. If your team already relies on Redux middleware, that is the reason to pick this over a non-Redux state library: you keep the middleware and DevTools you have, and change the authoring style on top.

## Maintenance, licence and what an upgrade costs

The repository is not archived. The last push was on 2026-06-30, and the most recent release listed is v6.1.1 on 2026-04-08. The v6.1.0 release came on 2025-02-19, so the stable line moves slowly between releases. The repository is on the master branch and package.json declares version 7.0.0-beta.2, which is consistent with the README's statement that v7 has not shipped as stable.

Licensing is straightforward: MIT, and the README's badge links to the MIT licence text. MIT permits commercial use and modification provided the copyright notice and permission notice are retained. That is the extent of what the repository states; it is not legal advice and your own counsel should review anything you redistribute.

The upgrade cost is the part worth budgeting. The README says the public store and model API is unchanged from v6 and the library is feature-complete, but also that the v7 line may still change before stable. So the migration from v6 to v7 is described as low-risk at the API level, while the risk sits in the beta period itself. The v6 to v7 upgrade guide is the document to read before you start, and the v6 docs site is where you look if you decide to stay put. The repository also carries a CHANGELOG.md, which is where release-by-release detail lives.

## Conclusion

Adopt easy-peasy if you want Redux's middleware and DevTools ecosystem behind a smaller API, and you are willing to track the v7 beta or stay on v6. Do not adopt it if you need a stable v7 today or cannot accept that the beta API may shift before release. Before committing, read the v6 to v7 upgrade guide on easy-peasy.dev and confirm which dist-tag your install resolves to, because npm install easy-peasy and npm install easy-peasy@beta do not give the same version.

## FAQ

### How do you use easy-peasy in a React app?

Create a store with createStore, wrap your component tree in StoreProvider, then read state with useStoreState and dispatch with useStoreActions inside any component below the provider. The README shows this as a three-step flow: create your store, wrap your application, use the store.

### Is easy-peasy free?

Yes. The repository is licensed under MIT, and the README's licence badge points at the MIT licence text. MIT allows commercial use and modification provided the copyright and permission notices are kept.

### What is easy-peasy?

It is a state management library for React, described in the README as an abstraction of Redux with a reimagined API focused on developer experience. It offers a hooks-based API, TypeScript support, middleware support and Redux Dev Tools integration.

## Sources

- [ctrlplusb/easy-peasy on GitHub](https://github.com/ctrlplusb/easy-peasy)
- [License: MIT](https://github.com/ctrlplusb/easy-peasy/blob/master/LICENSE)
- [Project website](https://easy-peasy.dev)
- [README](https://github.com/ctrlplusb/easy-peasy/blob/master/README.md)
- [Releases](https://github.com/ctrlplusb/easy-peasy/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/ctrlplusb-easy-peasy
