Skip to main content

What is Kea?

Heavyweight state management for React

Kea is a complete framework for managing state in React webapps.

Kea organises state in containers called logic, which are pretty big and pretty opinionated units of state, especially when compared to other solutions that are built around atoms, molecules, or context objects.

Kea doesn't limit itself to simple state management. Kea also provides standard solutions to common tasks like routing, data loading, and form handling. All through cleverly nested logic builders.

Kea believes the rigidity in its core structure and its set of standard tools introduce a lot of flexibility in your application: you can actually focus on what matters! The framework gets out of your way, as it should.

What's a logic?

A logic is created by passing an array of logic builders to kea([]), such as actions() and reducers():

For example:

import { kea, actions, reducers } from 'kea'

const loginLogic = kea([
actions({
setUsername: (username: string) => ({ username }),
}),
reducers({
username: ['keajs', { setUsername: (_, { username }) => username }],
}),
])

Here we created a logic with one action, setUsername, and one value, exposed through a username reducer.

The resulting loginLogic can be used directly:

loginLogic.mount()
loginLogic.actions.setUsername('posthog')
loginLogic.values.username === 'posthog'

... or with hooks in a React component, to tie its mount/unmount lifecycle to the component's.

import { useValues, useActions } from 'kea'

function Login() {
const { setUsername } = useActions(loginLogic)
const { username } = useValues(loginLogic)
// ...
}

Core building blocks

Just like Redux, Kea uses actions, reducers, and selectors as its core building blocks.

These provide a stable foundation that all other features are built on.

  • Think of actions as a unified messaging bus that every part of your app uses to communicate.
  • Think of reducers as the only "write" operation in the entire system, and only in response to actions.
  • Think of selectors as the only "read" operation in the entire system. They're exposed as values, and also act as the computed caching layer.

You can run side-effects in response to actions with listeners, or subscribe to changes in values with subscriptions.

Redux Devtools with Inline Paths

There are plugins that simplify data loading, forms, routing, and other common tasks.

It's a lot of approachable and hopefully familiar code, but with a few twists (look for breakpoints), and in a nice package.

Data layer

When fully deployed, Kea acts as a separate data layer, which communicates with React through a strict boundary of actions, props and values. You should aim to keep as much of your data, and its manipulations within Kea's data layer, leaving React to do an amazing job as the view layer.

That's right, MVC is back, but it's just D&V this time!

Kea discourages the use of useState and useEffect for local scene data, because local state inevitably becomes global.

Kea discourages the use of Context because you shouldn't re-render everything, everytime, always, everytime. Always.

Kea believes that it's hard enough to get your data layer right, so why burden yourself even more, by cramming it in a DOM-like tree of React nodes?

Kea thinks layers shield complexity, and promote simplicity.

Bring back the layers!

To take full advantage of Kea, think of it as a self-sufficient data layer between your APIs and React, shielding both from each other:

How to learn Kea?

Start by reading through the Core and Meta sections in the sidebar, and then just going for it.

You can also have a look at the ever expanding list of video tutorials to quickly get up to speed. Start with the basics.

I'm working on providing better tutorials and documentation, but these things take time. Subscribe to the Kea mailing list to get the latest updates.

History

The Kea project began in 2015 when I took on a job to build an app with React and Redux.

Redux of 2015 was fine, but I kept writing very similar code over and over again. Its main criticism at the time was "too much boilerplate", thus back then everyone invented their own abstractions. This includes the Redux maintainers themselves, but only later in 2018 with Redux Toolkit.

We're still in 2015. My loose collection of helper functions grew into the first public release of Kea, version 0.1 at the start of 2016. By 2019, over three years, this had gradualy evolved into a unified high level abstraction over Redux with Kea 0.28.

I had developed several large webapps with Kea and the kea-saga plugin by then. It felt like coding at the bleeding edge of React + Redux development.

Then, in 2019, something happened. React v16.8 introduced Hooks, and to keep up, Kea went through a long 1.0 rewrite (5+ months of hard work over 300+ commits), introduced listeners to replace sagas, and soon made things even simpler with Kea 2.0. Years 2020-2021 saw innovation in type generation, the maturation of the loaders and router plugins, a new testing framework, and a solidification of a data-first mindset to guide development.

Now in early 2022, it's time for yet another shift. Kea 3.0 introduces builders, making it possible to build abstractions on top of Kea on a whole new level. The new kea-forms plugin takes full advantage of this new power.

What's a "kea"?

According to Wikipedia:

The kea (/ˈkiːə/; Māori: [kɛ.a]) is a species of large parrot found in the forested and alpine regions of the South Island of New Zealand.

Kea are known for their intelligence and curiosity. Kea can solve logical puzzles, such as pushing and pulling things in a certain order to get to food, and will work together to achieve a certain objective.

Check out some videos to see this magnificent bird in action.

Kea the parrot always finds the shortest and the smartest way to achieve a goal, such as getting food from a maze.

Kea the framework follows a similar approach. It offers a simple and straightforward solution to the complicated problem of state management.

Plus, when I started to learn React, I was on a plane back to Belgium from a holiday in New Zealand, having just seen the bird a week before. Plus it was available on npm.

Questions & Answers

Ask questions about this page here.