https://github.com/statelyai/xstate Skip to content Toggle navigation Sign up * Product + Actions Automate any workflow + Packages Host and manage packages + Security Find and fix vulnerabilities + Codespaces Instant dev environments + Copilot Write better code with AI + Code review Manage code changes + Issues Plan and track work + Discussions Collaborate outside of code + Explore + All features + Documentation + GitHub Skills + Blog * Solutions + For + Enterprise + Teams + Startups + Education + By Solution + CI/CD & Automation + DevOps + DevSecOps + Case Studies + Customer Stories + Resources * Open Source + GitHub Sponsors Fund open source developers + The ReadME Project GitHub community articles + Repositories + Topics + Trending + Collections * Pricing [ ] * # In this repository All GitHub | Jump to | * No suggested jump to results * # In this repository All GitHub | Jump to | * # In this organization All GitHub | Jump to | * # In this repository All GitHub | Jump to | Sign in Sign up {{ message }} statelyai / xstate Public * * Notifications * Fork 1.1k * Star 23.3k State machines and statecharts for the modern web. xstate.js.org/docs License MIT license 23.3k stars 1.1k forks Star Notifications * Code * Issues 127 * Pull requests 114 * Discussions * Actions * Projects 2 * Security * Insights More * Code * Issues * Pull requests * Discussions * Actions * Projects * Security * Insights statelyai/xstate This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository. main Switch branches/tags [ ] Branches Tags Could not load branches Nothing to show {{ refName }} default View all branches Could not load tags Nothing to show {{ refName }} default View all tags Name already in use A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch? Cancel Create 148 branches 266 tags Code * Local * Codespaces * Clone HTTPS GitHub CLI [https://github.com/s] Use Git or checkout with SVN using the web URL. [gh repo clone statel] Work fast with our official CLI. Learn more. * Open with GitHub Desktop * Download ZIP Sign In Required Please sign in to use Codespaces. Launching GitHub Desktop If nothing happens, download GitHub Desktop and try again. Launching GitHub Desktop If nothing happens, download GitHub Desktop and try again. Launching Xcode If nothing happens, download Xcode and try again. Launching Visual Studio Code Your codespace will open once ready. There was a problem preparing your codespace, please try again. Latest commit @kevinmaes kevinmaes Fix warnings and TS errors for xstate/graph tests (#3907) ... 7401a61 Mar 24, 2023 Fix warnings and TS errors for `xstate/graph` tests (#3907) * Add predictableActionArguments: true to silence warnings * Use createMachine and fix target state in config * Add predictableActionArguments: true to silence warnings * Fix path to getMachineShortestPaths * Add changeset * Revert "Add predictableActionArguments: true to silence warnings" This reverts commit 75bc6c8. * Revert "Add predictableActionArguments: true to silence warnings" This reverts commit a7d1c0c. * Revert "Add changeset" This reverts commit 5f62ba0. * Remove predictableActionArguments from machine config 7401a61 Git stats * 5,231 commits Files Permalink Failed to load latest commit information. Type Name Latest commit message Commit time .changeset-stable-release-channel Prepare files for a new alpha release of @xstate/test March 7, 2023 13:51 .changeset-xstate-test-alpha Switch back Changesets files to the stable release channel March 7, 2023 14:08 .changeset Version Packages (#3914) March 23, 2023 15:11 .codesandbox Update a bunch of GitHub actions and bump node version on CI (#3386) June 7, 2022 14:52 .github Use setup-node script to set node 16 (#3866) February 28, 2023 08:37 .vscode Add .vscode/launch.json to make it easy to debug Jest tests within ... March 7, 2022 21:24 docs Adding an example https://towerofhanoi.app (#3863) February 27, 2023 18:44 examples Add @xstate/solid (#2932) January 27, 2023 09:26 packages Fix warnings and TS errors for xstate/graph tests (#3907) March 24, 2023 11:24 scripts Update dependencies in example directories July 4, 2022 17:12 templates Fix links (#3841) February 17, 2023 09:54 .gitignore Ignore files from JetBrains IDE (#3729) December 28, 2022 12:03 .node-version Update a bunch of GitHub actions and bump node version on CI (#3386) June 7, 2022 14:52 .prettierrc Prettier + adding unit tests for guard conditions December 5, 2017 23:39 CODE_OF_CONDUCT.md Reformat some doc files with Prettier January 26, 2022 12:40 CONTRIBUTING.md Change github.com/davidkpiano -> github.com/statelyai January 24, 2022 08:37 ISSUE_TEMPLATE.md Change github.com/davidkpiano -> github.com/statelyai January 24, 2022 08:37 LICENSE Initial commit September 14, 2015 11:04 README.md Add Transloadit sponsor (#3876) March 5, 2023 04:21 jest.config.js Remove xstate-dev February 3, 2021 18:37 lerna.json Migrate to Yarn & move core package to separate directory October 5, 2019 15:57 migration.md Machine -> createMachine May 3, 2021 08:57 package.json [xstate/react] Add createActorContext() (#3778) January 26, 2023 09:51 tsconfig.base.json chore: add skipLibCheck: true to tsconfig.base.json November 28, 2019 09:14 tsconfig.monorepo.json Add @xstate/solid (#2932) January 27, 2023 09:26 tslint.json Add withServiceScope April 28, 2019 11:10 yarn.lock Fixed inference for assign using PropertyAssigner (#3818) February 9, 2023 18:23 View code [ ] Packages Templates Super quick start Promise example Visualizer Why? Finite State Machines Hierarchical (Nested) State Machines Parallel State Machines History States Sponsors SemVer Policy Breaking changes TypeScript changes Packages README.md XState logotype [JavaScript state machines and statecharts] npm version [6874747073] JavaScript and TypeScript finite state machines and statecharts for the modern web. Read the documentation Explore our catalogue of examples [?] Create state machines with the Stately Editor Download our VS Code extension Adheres to the SCXML specification Chat on the Stately Discord Community Packages * xstate - Core finite state machine and statecharts library + interpreter * @xstate/fsm - Minimal finite state machine library * @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/solid - Solid hooks and utilities for using XState in Solid applications * @xstate/test - Model-Based-Testing utilities (using XState) for testing any software * @xstate/inspect - Inspection utilities for XState Templates Get started by forking one of these templates on CodeSandbox: * XState Template - no framework * XState + TypeScript Template - no framework * XState + React Template * XState + React + TypeScript Template * XState + Vue Template * XState + Vue 3 Template * XState + Svelte Template Super quick start npm install xstate import { createMachine, interpret } from 'xstate'; // Stateless machine definition // machine.transition(...) is a pure function used by the interpreter. const toggleMachine = createMachine({ id: 'toggle', 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' Promise example See the visualization on stately.ai/viz See the code import { createMachine, interpret, assign } from 'xstate'; const fetchMachine = createMachine({ id: 'Dog API', initial: 'idle', context: { dog: null }, states: { idle: { on: { FETCH: 'loading' } }, loading: { invoke: { id: 'fetchDog', src: (context, event) => fetch('https://dog.ceo/api/breeds/image/random').then((data) => data.json() ), onDone: { target: 'resolved', actions: assign({ dog: (_, event) => event.data }) }, onError: 'rejected' }, on: { CANCEL: 'idle' } }, resolved: { type: 'final' }, rejected: { on: { FETCH: 'loading' } } } }); const dogService = interpret(fetchMachine) .onTransition((state) => console.log(state.value)) .start(); dogService.send('FETCH'); * Visualizer * Why? * Finite State Machines * Hierarchical (Nested) State Machines * Parallel State Machines * History States Visualizer Visualize, simulate, inspect, and share your statecharts in XState Viz XState Viz stately.ai/viz 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 (For XState specific questions, please use the GitHub Discussions) Finite State Machines Finite states Open in Stately Viz import { createMachine } from 'xstate'; const lightMachine = createMachine({ 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 Hierarchical states Open in Stately Viz import { createMachine } from 'xstate'; const pedestrianStates = { initial: 'walk', states: { walk: { on: { PED_TIMER: 'wait' } }, wait: { on: { PED_TIMER: 'stop' } }, stop: {} } }; const lightMachine = createMachine({ 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 Parallel states Open in Stately Viz const wordMachine = createMachine({ 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 History state Open in Stately Viz const paymentMachine = createMachine({ 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 Special thanks to the sponsors who support this open-source project: Transloadit logo Transloadit SemVer Policy We understand the importance of the public contract and do not intend to release any breaking changes to the runtime API in a minor or patch release. We consider this with any changes we make to the XState libraries and aim to minimize their effects on existing users. Breaking changes XState executes much of the user logic itself. Therefore, almost any change to its behavior might be considered a breaking change. We recognize this as a potential problem but believe that treating every change as a breaking change is not practical. We do our best to implement new features thoughtfully to enable our users to implement their logic in a better, safer way. Any change could affect how existing XState machines behave if those machines are using particular configurations. We do not introduce behavior changes on a whim and aim to avoid making changes that affect most existing machines. But we reserve the right to make some behavior changes in minor releases. Our best judgment of the situation will always dictate such changes. Please always read our release notes before deciding to upgrade. TypeScript changes We also reserve a similar right to adjust declared TypeScript definitions or drop support for older versions of TypeScript in a minor release. The TypeScript language itself evolves quickly and often introduces breaking changes in its minor releases. Our team is also continuously learning how to leverage TypeScript more effectively - and the types improve as a result. For these reasons, it is impractical for our team to be bound by decisions taken when an older version of TypeScript was its latest version or when we didn't know how to declare our types in a better way. We won't introduce declaration changes often - but we are more likely to do so than with runtime changes. Packages Most of the packages in the XState family declare a peer dependency on XState itself. We'll be cautious about maintaining compatibility with already-released packages when releasing a new version of XState, but each release of packages depending on XState will always adjust the declared peer dependency range to include the latest version of XState. For example, you should always be able to update xstate without @xstate/react. But when you update @xstate/react, we highly recommend updating xstate too. About State machines and statecharts for the modern web. xstate.js.org/docs Topics javascript workflow typescript interpreter state-management fsm state-machine statechart state orchestration visualizer finite-state-machine hacktoberfest scxml statecharts Resources Readme License MIT license Code of conduct Code of conduct Stars 23.3k stars Watchers 187 watching Forks 1.1k forks Releases 203 xstate@4.37.1 Latest Mar 23, 2023 + 202 releases Sponsor this project * * open_collective opencollective.com/xstate Learn more about GitHub Sponsors Packages 0 No packages published Used by 198k * @nataliesmyth * @heart569522 * @githubrepo88 * @Boston343 * @mark-hypeit * @justinmahar * @hanszaishengzhang * @petersowa + 198,277 Contributors 315 * @davidkpiano * @Andarist * @mattpocock * @github-actions[bot] * @santicros * @laurakalbag * @mogsie * @jamesopstad * @hnordt * @edsilv * @nlopin + 304 contributors Languages * TypeScript 97.4% * JavaScript 1.2% * Other 1.4% Footer (c) 2023 GitHub, Inc. Footer navigation * Terms * Privacy * Security * Status * Docs * Contact GitHub * Pricing * API * Training * Blog * About You can't perform that action at this time. You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.