All Projects β†’ statelyai β†’ xstate

statelyai / xstate

Licence: MIT license
State machines and statecharts for the modern web.

Programming Languages

typescript
32286 projects
javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to xstate

Xstate
State machines and statecharts for the modern web.
Stars: ✭ 18,300 (-14.03%)
Mutual labels:  interpreter, state-management, state-machine, statechart, state, orchestration, visualizer, scxml
statemachine-go
🚦 Declarative Finite-State Machines in Go
Stars: ✭ 47 (-99.78%)
Mutual labels:  fsm, state-machine, state, finite-state-machine, statecharts
use-state-machine
Use Finite State Machines with React Hooks
Stars: ✭ 28 (-99.87%)
Mutual labels:  state-management, fsm, state-machine, finite-state-machine
Finity
A finite state machine library for Node.js and the browser with a friendly configuration DSL.
Stars: ✭ 88 (-99.59%)
Mutual labels:  fsm, state-machine, state, finite-state-machine
simple-state-machine
A simple Java state machine for Spring Boot projects
Stars: ✭ 25 (-99.88%)
Mutual labels:  fsm, state-machine, statechart, finite-state-machine
ScxmlEditor-Tutorial
ScxmlEditor - powerful tool for creating, editing and debugging scxml files
Stars: ✭ 33 (-99.84%)
Mutual labels:  fsm, statechart, state, scxml
StateBuilder
State machine code generator for C++ and Java.
Stars: ✭ 30 (-99.86%)
Mutual labels:  state-machine, statechart, state, finite-state-machine
FiniteStateMachine
This project is a finite state machine designed to be used in games.
Stars: ✭ 45 (-99.79%)
Mutual labels:  fsm, state-machine, finite-state-machine
Nanostate
🚦- Small Finite State Machines
Stars: ✭ 151 (-99.29%)
Mutual labels:  fsm, state-machine, finite-state-machine
stateless
Finite State Machine porting from Stateless C#
Stars: ✭ 25 (-99.88%)
Mutual labels:  fsm, state-machine, finite-state-machine
tstate-machine
TypeScript implementation of State Manager(like StateMachine)
Stars: ✭ 20 (-99.91%)
Mutual labels:  state-management, state-machine, state
Django Fsm
Django friendly finite state machine support
Stars: ✭ 1,898 (-91.08%)
Mutual labels:  fsm, state-machine, finite-state-machine
Afsm
C++14 Finite State Machine library
Stars: ✭ 113 (-99.47%)
Mutual labels:  fsm, state-machine, finite-state-machine
qp-arduino
QP real-time embedded frameworks/RTOS for Arduino (AVR and SAM)
Stars: ✭ 37 (-99.83%)
Mutual labels:  fsm, state-machine, statechart
Jstate
Advanced state machines in Java.
Stars: ✭ 84 (-99.61%)
Mutual labels:  fsm, state-machine, finite-state-machine
Fluent State Machine
Fluent API for creating state machines in C#
Stars: ✭ 195 (-99.08%)
Mutual labels:  fsm, state-machine, finite-state-machine
kstatemachine
KStateMachine is a Kotlin DSL library for creating finite state machines (FSM) and hierarchical state machines (HSM).
Stars: ✭ 63 (-99.7%)
Mutual labels:  state-management, fsm, state-machine
Machinery
State machine thin layer for structs (+ GUI for Phoenix apps)
Stars: ✭ 367 (-98.28%)
Mutual labels:  state-management, state-machine, state
xstate-cpp-generator
C++ State Machine generator for Xstate
Stars: ✭ 33 (-99.84%)
Mutual labels:  state-management, fsm, state-machine
Little State Machine
πŸ“  React custom hook for persist state management
Stars: ✭ 654 (-96.93%)
Mutual labels:  state-management, state-machine, state


XState
JavaScript state machines and statecharts

npm version

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

Templates

Get started by forking one of these templates on CodeSandbox:

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

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:

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' }

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.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].