xstate


TravisnpmStatecharts gitter chat

Functional, stateless JavaScript finite state machines and statecharts.

import { Machine } from 'xstate'; const toggleMachine = Machine({ initial: 'inactive', states: { inactive: { on: { TOGGLE: 'active' } }, active: { on: { TOGGLE: 'inactive' } } }
}); let currentState = toggleMachine.initialState; function send(event) { currentState = toggleMachine.transition(currentState, event); console.log(currentState.value);
} send('TOGGLE'); send('TOGGLE'); 

📖 Read the documentation!

:new: Preview and simulate your statecharts in the xstate visualizer (beta)!

xstate visualizer

With sketch.systems, you can now copy-paste your state machine sketches as XState-compatible JSON!

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:

  1. npm install xstate --save
  2. import { Machine } from 'xstate';
Light Machine
import { Machine } from 'xstate'; const lightMachine = Machine({ key: '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; 
Hierarchical Light Machine
import { Machine } from 'xstate'; const pedestrianStates = { initial: 'walk', states: { walk: { on: { PED_TIMER: 'wait' } }, wait: { on: { PED_TIMER: 'stop' } }, stop: {} }
}; const lightMachine = Machine({ key: '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; lightMachine.transition('red.walk', 'PED_TIMER').value; 

Object notation for hierarchical states:


const waitState = lightMachine.transition({ red: 'walk' }, 'PED_TIMER').value; lightMachine.transition(waitState, 'PED_TIMER').value; lightMachine.transition({ red: 'stop' }, 'TIMER').value; 
Parallel state machine
const wordMachine = Machine({ parallel: true, 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; const nextState = wordMachine.transition( { bold: 'off', italics: 'off', underline: 'on', list: 'bullets' }, 'TOGGLE_ITALICS'
).value; 

History States

Machine with history state
const paymentMachine = Machine({ initial: 'method', states: { method: { initial: 'cash', states: { cash: { on: { SWITCH_CHECK: 'check' } }, check: { on: { SWITCH_CASH: 'cash' } }, hist: { history: true } }, on: { NEXT: 'review' } }, review: { on: { PREVIOUS: 'method.hist' } } }
}); const checkState = paymentMachine.transition('method.cash', 'SWITCH_CHECK'); const reviewState = paymentMachine.transition(checkState, 'NEXT'); const previousState = paymentMachine.transition(reviewState, 'PREVIOUS').value;