Stately
Core Concepts

XState

XState is a state management and orchestration solution for JavaScript and TypeScript apps.

It uses event-driven programming, state machines, statecharts, and the actor model to handle complex logic in predictable, robust, and visual ways. XState provides a powerful and flexible way to manage application and workflow state by allowing developers to model logic as actors and state machines. It integrates well with React, Vue, Svelte, and other frameworks and can be used in the frontend, backend, or wherever JavaScript runs.

Want to find out more about state machines? Read our introduction.

Installation

XState is available on npm:

npm install xstate
pnpm install xstate
yarn add xstate

Create a simple machine

import { createMachine, assign, createActor } from 'xstate';

const countMachine = createMachine({
  context: {
    count: 0,
  },
  on: {
    INC: {
      actions: assign({
        count: ({ context }) => context.count + 1,
      }),
    },
    DEC: {
      actions: assign({
        count: ({ context }) => context.count - 1,
      }),
    },
    SET: {
      actions: assign({
        count: ({ event }) => event.value,
      }),
    },
  },
});

const countActor = createActor(countMachine).start();

countActor.subscribe((state) => {
  console.log(state.context.count);
});

countActor.send({ type: 'INC' });
// logs 1
countActor.send({ type: 'DEC' });
// logs 0
countActor.send({ type: 'SET', value: 10 });
// logs 10

Check out more cheatsheet examples.

Create a more complex machine

import { createMachine, assign, createActor } from 'xstate';

const textMachine = createMachine({
  context: {
    committedValue: '',
    value: '',
  },
  initial: 'reading',
  states: {
    reading: {
      on: {
        'text.edit': { target: 'editing' },
      },
    },
    editing: {
      on: {
        'text.change': {
          actions: assign({
            value: ({ event }) => event.value,
          }),
        },
        'text.commit': {
          actions: assign({
            committedValue: ({ context }) => context.value,
          }),
          target: 'reading',
        },
        'text.cancel': {
          actions: assign({
            value: ({ context }) => context.committedValue,
          }),
          target: 'reading',
        },
      },
    },
  },
});

const textActor = createActor(textMachine).start();

textActor.subscribe((state) => {
  console.log(state.context.value);
});

textActor.send({ type: 'text.edit' });
// logs ''
textActor.send({ type: 'text.change', value: 'Hello' });
// logs 'Hello'
textActor.send({ type: 'text.commit' });
// logs 'Hello'
textActor.send({ type: 'text.edit' });
// logs 'Hello'
textActor.send({ type: 'text.change', value: 'Hello world' });
// logs 'Hello world'
textActor.send({ type: 'text.cancel' });
// logs 'Hello'

Download the XState VS Code extension

The XState VS Code extension does not fully support XState v5 yet.

Read more about our developer tools.

Packages

  • 🤖 xstate: Core finite state machine and statecharts library + actors
  • 📉 @xstate/graph: Graph traversal utilities for XState
  • ⚛️ @xstate/react: React hooks and utilities for using XState in React applications
  • 💚 @xstate/vue: Vue composition functions and utilities for using XState in Vue applications
  • 🎷 @xstate/svelte: Svelte utilities for using XState in Svelte applications
  • @xstate/test: Model-Based-Testing utilities (using XState) for testing any software

On this page