Thunks are the simplest ways to define side effects with Redux.


First install the kea-thunk and redux-thunk packages:

yarn add kea-thunk redux-thunk
npm install --save kea-thunk redux-thunk

Then you have a few ways to install the plugin:

// the cleanest way
import thunkPlugin from 'kea-thunk'
import { getStore } from 'kea'

const store = getStore({
  plugins: [ thunkPlugin ]

// another way
import thunkPlugin from 'kea-thunk'
import { activatePlugin } from 'kea'


// the shortest way
import 'kea-thunk/install'

Use whichever way is most convenient for your setup.

Note that the kea-thunk plugin needs to be installed globally as it needs to add its middleware to the store. You can't use it as a local plugin inside kea({}) calls.

If you have configured your store through getStore(), you're all set!


You define thunks in a block called thunks. Here are some examples:

const delay = (ms) => new Promise(resolve => window.setTimeout(resolve, ms))

const logic = kea({
  actions: ({ constants }) => ({
    updateName: name => ({ name })

  thunks: ({ actions, get, fetch, dispatch, getState }) => ({
    updateNameAsync: async name => {
      await delay(1000)            // standard promise
      await actions.anotherThunk() // another thunk action
      actions.updateName(name)     // not a thunk, so no async needed
      dispatch({ type: 'RANDOM_REDUX_ACTION' }) // random redux action

      get('name') // 'chirpy'
      fetch('name', 'otherKey') // { name: 'chirpy', otherKey: undefined }
    anotherThunk: async () => {
      // do something

  reducers: ({ actions, constants }) => ({
    name: ['chirpy', PropTypes.string, {
      [actions.updateName]: (state, payload) =>

As you can see, you have access to the standard Redux dispatch and getState methods. However you don't need to call dispatch before any action in the actions object. They are wrapped automatically.