Skip to content

Guide · Open source

How to use XState: state machines and actors in JavaScript

Updated · written with AI from the project's own documentation and checked against our catalogue data

XState is a library for managing state in JavaScript and TypeScript apps, on the frontend or backend. You describe how your logic moves between states and reacts to events, using state machines, statecharts, and actors, so the behavior stays predictable and can be visualized. This guide shows you how to install it, write a small machine, run it as an actor, and decide when the lighter @xstate/store package fits better.

XStatestatelyai/xstate · ★ 30.4k · MIT

Quick start

  1. 1Check Node.js. Confirm Node.js is installed, since the source lists it as the prerequisite.
  2. 2Install xstate. Run npm install xstate in your project folder.
  3. 3Define a machine. Use createMachine with an id, an initial state, context, and states with on transitions.
  4. 4Create an actor. Call createActor with your machine so it becomes a running instance.
  5. 5Subscribe and start. Subscribe to state updates, then call start() on the actor.
  6. 6Send events. Use send with an event object whose type matches a key in your on map.
  7. 7Try @xstate/store if you need less. Install @xstate/store for simple event-based state when full machines are more than you need.

What you need before you install XState

XState runs in JavaScript and TypeScript projects. The source lists Node.js as the prerequisite for installing it with a package manager. The guide assumes you are comfortable with JavaScript or TypeScript and with the basic idea of state, such as a value that changes over time.

  • Node.js installed on your machine
  • A JavaScript or TypeScript project
  • Basic familiarity with JavaScript or TypeScript

Install XState with npm

Run the install command from your project folder. This adds the xstate package so you can import its functions in your code.

npm install xstate

Write a state machine with createMachine

A state machine is a set of named states, the events it accepts, and the transitions between states. In the example below, the machine has two states, inactive and active. The TOGGLE event moves it between them. The active state also uses an entry action with assign to increase a count each time the machine enters that state.

The machine itself only describes the logic. It does not run until you create an actor from it.

  • id gives the machine a name.
  • initial sets the starting state.
  • context holds data that can change over time.
  • on maps event types, such as TOGGLE, to target states.
import { createMachine, createActor, assign } from 'xstate'; const toggleMachine = createMachine({ id: 'toggle', initial: 'inactive', context: { count: 0 }, states: { inactive: { on: { TOGGLE: { target: 'active' } } }, active: { entry: assign({ count: ({ context }) => context.count + 1 }), on: { TOGGLE: { target: 'inactive' } } } } });

Run the machine as an actor

An actor is a running instance of the machine logic, similar in role to a store. You create it with createActor, subscribe to state changes, start it, and send events. Each subscriber receives the current state value and context.

Sending TOGGLE twice in the example moves the machine from inactive to active and back again, and the count increases when it becomes active.

  • Call createActor(machine) to create the instance.
  • Use subscribe to log or react to each new state.
  • Call start() before sending events.
  • Use send({ type: 'TOGGLE' }) to trigger a transition.
const toggleActor = createActor(toggleMachine); toggleActor.subscribe((state) => console.log(state.value, state.context)); toggleActor.start(); toggleActor.send({ type: 'TOGGLE' }); toggleActor.send({ type: 'TOGGLE' });

Use @xstate/store for simpler state

Not every app needs full machines and statecharts. The @xstate/store package is a separate, small event-based store. It is similar in spirit to Redux or Zustand but, per the source, with less boilerplate. You define context and handlers for each event, then send events to update it.

You can use @xstate/store on its own, or move to full XState machines when your logic gets more complex. The two work well together, but you do not need one to use the other.

npm install @xstate/store

Choose a starting point from the templates

The project lists templates you can fork on CodeSandbox or open on StackBlitz. They cover plain TypeScript, React, Vue and Svelte, and each uses XState v5 with TypeScript. These are useful if you want a working project before writing your own setup.

  • Vanilla TypeScript with no framework
  • React with TypeScript
  • Vue with TypeScript
  • Svelte with TypeScript

What people use it for

  • Managing a multi-step UI flow with many interacting states, such as a form wizard
  • Modeling a multi-step workflow or process in backend code
  • Writing state logic that can be drawn as a diagram
  • Using a state-machine approach in React, Vue or Svelte apps
  • Keeping simple app state in a small store with @xstate/store

Frequently asked questions

How do I install XState?

Run npm install xstate in your project. The source lists Node.js as the prerequisite for this package-manager install.

Is XState free to use?

XState is released under the MIT licence, according to the project's listing. Check the repository's licence file for the full terms.

Does XState have dependencies?

The README says XState has zero dependencies. It is a library for JavaScript and TypeScript apps, usable on the frontend or backend.

Can I use XState with React, Vue or Svelte?

Yes. The project provides templates for React, Vue and Svelte, and separate packages such as @xstate/react and @xstate/vue for those frameworks.

What is the difference between xstate and @xstate/store?

xstate covers state machines, statecharts, actors and orchestration. @xstate/store is a smaller event-based store for cases that do not need full machines, and it works with or without xstate.

When should I not use XState?

The source says simple apps with only a few pieces of state may not need it, since a basic store or plain variables can be enough. The concepts add overhead, and beginners may find them hard at first.

New agent skills, repos and AI tools — every week

The best new skills and open-source projects, the fastest-growing repos, and one free prompt. Five minutes to read. Unsubscribe anytime.

Our verdict

XState suits frontend developers with complex, interacting UI states and teams modeling multi-step workflows in backend code, especially when a diagram of the logic helps. If your app has only a few pieces of state, a basic store, plain variables, or the smaller @xstate/store package is likely the better choice.

Install options & downloads