Stately
Guides

Usage with Immer

Immer is a library that makes it more convenient to work with updating data immutably. It can be used with XState to immutably update context in assignments.

It is recommended to use Immer directly with XState instead of the @xstate/immer package, which is deprecated.

Installation

Install the latest versions of xstate and immer from npm:

npm install xstate immer
pnpm install xstate immer
yarn add xstate immer

See the Immer installation docs for more information.

Immer usage

XState already allows you to immutably update context partially or completely in assign actions. However, for more complex scenarios, you may want to use Immer to update context in a less verbose way.

import { createMachine, assign } from 'xstate';
import { produce } from 'immer';

const machine = createMachine({
  id: 'todos',
  context: {
    todos: [],
    filter: 'all',
  },
  // ...
  on: {
    'todo.complete': {
      // Using Immer to update a single context property
      actions: assign({
        todos: ({ context, event }) =>
          produce(context.todos, (draftTodos) => {
            const todo = draftTodos.find((t) => t.id === event.todo.id);
            todo.completed = true;
          }),
      }),
    },
    'todos.add': {
      // Using Immer to update multiple context properties
      actions: assign(({ context, event }) =>
        produce(context, (draftContext) => {
          draftContext.todos.push({
            id: event.todo.id,
            description: event.todo.description,
            completed: false,
          });

          if (draftContext.filter === 'all') {
            draftContext.filter = 'active';
          }
        }),
      ),
    },
  },
});

On this page