Package Exports
- xstate
- xstate/lib/actions
- xstate/lib/graph
- xstate/lib/interpreter
- xstate/lib/types
- xstate/lib/utils
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (xstate) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
JavaScript state machines and statecharts
Functional, stateless JavaScript finite state machines and statecharts.
Adheres to the SCXML specification.
Version 3.x to 4 Migration Guide
Super quick start
npm i xstate -S
import { Machine } from 'xstate';
import { interpret } from 'xstate/lib/interpreter'; // or use your own interpreter!
// Stateless machine definition
// machine.transition(...) is a pure function used by the interpreter.
const toggleMachine = Machine({
initial: 'inactive',
states: {
inactive: { on: { TOGGLE: 'active' } },
active: { on: { TOGGLE: 'inactive' } }
}
});
// Machine instance with internal state
const toggleService = interpret(toggleMachine)
.onTransition(state => console.log(state.value))
.start();
// => 'inactive'
toggleService.send('TOGGLE');
// => 'active'
toggleService.send('TOGGLE');
// => 'inactive'
- Visualizer
- Why? (info about statecharts)
- Installation
- Finite State Machines
- Hierarchical (Nested) State Machines
- Parallel State Machines
- History States
Visualizer
🆕 Preview and simulate your statecharts in the XState visualizer (beta)!
Why?
Statecharts are a formalism for modeling stateful, reactive systems. This is useful for declaratively describing the behavior of your application, from the individual components to the overall application logic.
Read 📽 the slides (🎥 video) or check out these resources for learning about the importance of finite state machines and statecharts in user interfaces:
- Statecharts - A Visual Formalism for Complex Systems by David Harel
- The World of Statecharts by Erik Mogensen
- Pure UI by Guillermo Rauch
- Pure UI Control by Adam Solove
- Spectrum - Statecharts Community
Installation
npm install xstate --save
import { Machine } from 'xstate';
Finite State Machines

import { Machine } from 'xstate';
const lightMachine = Machine({
id: 'light',
initial: 'green',
states: {
green: {
on: {
TIMER: 'yellow'
}
},
yellow: {
on: {
TIMER: 'red'
}
},
red: {
on: {
TIMER: 'green'
}
}
}
});
const currentState = 'green';
const nextState = lightMachine.transition(currentState, 'TIMER').value;
// => 'yellow'
Hierarchical (Nested) State Machines

import { Machine } from 'xstate';
const pedestrianStates = {
initial: 'walk',
states: {
walk: {
on: {
PED_TIMER: 'wait'
}
},
wait: {
on: {
PED_TIMER: 'stop'
}
},
stop: {}
}
};
const lightMachine = Machine({
id: 'light',
initial: 'green',
states: {
green: {
on: {
TIMER: 'yellow'
}
},
yellow: {
on: {
TIMER: 'red'
}
},
red: {
on: {
TIMER: 'green'
},
...pedestrianStates
}
}
});
const currentState = 'yellow';
const nextState = lightMachine.transition(currentState, 'TIMER').value;
// => {
// red: 'walk'
// }
lightMachine.transition('red.walk', 'PED_TIMER').value;
// => {
// red: 'wait'
// }
Object notation for hierarchical states:
// ...
const waitState = lightMachine.transition({ red: 'walk' }, 'PED_TIMER').value;
// => { red: 'wait' }
lightMachine.transition(waitState, 'PED_TIMER').value;
// => { red: 'stop' }
lightMachine.transition({ red: 'stop' }, 'TIMER').value;
// => 'green'
Parallel State Machines

const wordMachine = Machine({
id: 'word',
type: 'parallel',
states: {
bold: {
initial: 'off',
states: {
on: {
on: { TOGGLE_BOLD: 'off' }
},
off: {
on: { TOGGLE_BOLD: 'on' }
}
}
},
underline: {
initial: 'off',
states: {
on: {
on: { TOGGLE_UNDERLINE: 'off' }
},
off: {
on: { TOGGLE_UNDERLINE: 'on' }
}
}
},
italics: {
initial: 'off',
states: {
on: {
on: { TOGGLE_ITALICS: 'off' }
},
off: {
on: { TOGGLE_ITALICS: 'on' }
}
}
},
list: {
initial: 'none',
states: {
none: {
on: { BULLETS: 'bullets', NUMBERS: 'numbers' }
},
bullets: {
on: { NONE: 'none', NUMBERS: 'numbers' }
},
numbers: {
on: { BULLETS: 'bullets', NONE: 'none' }
}
}
}
}
});
const boldState = wordMachine.transition('bold.off', 'TOGGLE_BOLD').value;
// {
// bold: 'on',
// italics: 'off',
// underline: 'off',
// list: 'none'
// }
const nextState = wordMachine.transition(
{
bold: 'off',
italics: 'off',
underline: 'on',
list: 'bullets'
},
'TOGGLE_ITALICS'
).value;
// {
// bold: 'off',
// italics: 'on',
// underline: 'on',
// list: 'bullets'
// }
History States

const paymentMachine = Machine({
id: 'payment',
initial: 'method',
states: {
method: {
initial: 'cash',
states: {
cash: { on: { SWITCH_CHECK: 'check' } },
check: { on: { SWITCH_CASH: 'cash' } },
hist: { type: 'history' }
},
on: { NEXT: 'review' }
},
review: {
on: { PREVIOUS: 'method.hist' }
}
}
});
const checkState = paymentMachine.transition('method.cash', 'SWITCH_CHECK');
// => State {
// value: { method: 'check' },
// history: State { ... }
// }
const reviewState = paymentMachine.transition(checkState, 'NEXT');
// => State {
// value: 'review',
// history: State { ... }
// }
const previousState = paymentMachine.transition(reviewState, 'PREVIOUS').value;
// => { method: 'check' }
Sponsors
Huge thanks to the following companies for sponsoring xstate
. You can sponsor further xstate
development on OpenCollective.