Skip to content
Version: XState v5

Quick start

This quick start guide will help you get started with XState and Stately Studio. You will learn how to create a state machine, create an actor from that state machine, send events to that actor, and observe the state changes.

Installing XState v5​

XState is a visual state management and orchestration library for JavaScript and TypeScript.

Install the XState v5 using your preferred package manager:

npm install xstate

Create a machine​

In XState, a machine is an object that contains all the logic for an actor. In this example, we will create a simple toggle machine that can be in one of two states: Active or Inactive. The toggle event will toggle the state between Active and Inactive.

import { createMachine } from 'xstate';

const toggleMachine = createMachine({
id: 'toggle',
initial: 'Inactive',
states: {
Inactive: {
on: { toggle: 'Active' },
},
Active: {
on: { toggle: 'Inactive' },
},
},
});

Read our introduction to state machines and statecharts to familiarize yourself with the concepts.

Create an actor and send events​

Machine logic can be used to create an actor. An actor is a running process that can receive messages (events), send messages and change its behavior based on the messages it receives.

import { createMachine, createActor } from 'xstate';

const toggleMachine = createMachine({
// Machine code from above
});

// Create an actor that you can send events to.
// Note: the actor is not started yet!
const actor = createActor(toggleMachine);

// Subscribe to snapshots (emitted state changes) from the actor
actor.subscribe((snapshot) => {
console.log('Value:', snapshot.value);
});

// Start the actor
actor.start(); // logs 'Inactive'

// Send events
actor.send({ type: 'toggle' }); // logs 'Active'
actor.send({ type: 'toggle' }); // logs 'Inactive'

Use delayed transitions​

Delayed transitions are transitions that automatically happen after a specified interval of time.

export const toggleMachine = createMachine({
id: 'toggle',
initial: 'Inactive',
states: {
Inactive: {
on: { toggle: 'Active' },
},
Active: {
on: { toggle: 'Inactive' },
after: { 2000: 'Inactive' },
},
},
});

Handle context data​

Context is how you store data in a state machine actor.

import { assign, createMachine } from 'xstate';

export const toggleMachine = createMachine({
id: 'toggle',
context: { count: 0 },
initial: 'Inactive',
states: {
Inactive: {
on: { toggle: 'Active' },
},
Active: {
entry: assign({
count: ({ context }) => context.count + 1
}),
on: { toggle: 'Inactive' },
after: { 2000: 'Inactive' },
},
},
});

Add input​

Input is how initial data can be provided to a machine actor.

Guards are used to conditionally allow or disallow transitions.

import { assign, createMachine } from 'xstate';

export const toggleMachine = createMachine({
id: 'toggle',
context: ({ input }) => ({
count: 0,
maxCount: input.maxCount
}),
initial: 'Inactive',
states: {
Inactive: {
on: {
toggle: {
// Only trigger toggle transition if count is less than maxCount
guard: ({ context }) => context.count < context.maxCount,
target: 'Active'
}
}
},
Active: {
entry: assign({
count: ({ context }) => context.count + 1
}),
on: { toggle: 'Inactive' },
after: { 2000: 'Inactive' },
},
},
});

const actor = createActor(toggleMachine, {
input: { maxCount: 10 }
});

actor.subscribe(snapshot => {
console.log('State:', snapshot.value);
});

actor.start();

actor.send({ type: 'toggle' });

Use your machine with a framework​

import { useMachine } from '@xstate/react';
import { toggleMachine } from './toggleMachine';

const App = () => {
const [state, send] = useMachine(toggleMachine);

return (
<div>
<div>Value: {state.value}</div>
<button onClick={() => send({ type: 'toggle' })}>
Toggle
</button>
</div>
);
};