Socket
Socket
Sign inDemoInstall

xstate

Package Overview
Dependencies
0
Maintainers
3
Versions
233
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

    xstate

Finite State Machines and Statecharts for the Modern Web.


Version published
Weekly downloads
1.3M
decreased by-14.7%
Maintainers
3
Created
Weekly downloads
ย 

Package description

What is xstate?

The xstate npm package is a library for creating, interpreting, and executing finite state machines and statecharts, as well as managing invocations of those machines as actors. It provides a robust framework for modeling and analyzing application logic in a composable and declarative way, which can help manage complex state logic in UIs, robotics, and other systems.

What are xstate's main functionalities?

Finite State Machines

This feature allows you to create simple finite state machines. The code sample demonstrates a toggle machine with two states: 'active' and 'inactive'.

{"import { Machine } from 'xstate';\n\nconst toggleMachine = Machine({\n  id: 'toggle',\n  initial: 'inactive',\n  states: {\n    inactive: { on: { TOGGLE: 'active' } },\n    active: { on: { TOGGLE: 'inactive' } }\n  }\n});"}

Statecharts

This feature allows you to create statecharts, which are an extension of state machines that can have hierarchical and parallel states. The code sample shows a traffic light machine with three states: 'green', 'yellow', and 'red'.

{"import { Machine } from 'xstate';\n\nconst lightMachine = Machine({\n  id: 'light',\n  initial: 'green',\n  states: {\n    green: { on: { TIMER: 'yellow' } },\n    yellow: { on: { TIMER: 'red' } },\n    red: { on: { TIMER: 'green' } }\n  }\n});"}

Interpreters

This feature allows you to interpret and execute the state machines and statecharts. The code sample demonstrates how to start a service that interprets the toggleMachine and logs state transitions.

{"import { interpret } from 'xstate';\n\nconst service = interpret(toggleMachine).onTransition((state) => console.log(state.value));\n\nservice.start();\nservice.send('TOGGLE');\nservice.send('TOGGLE');"}

Actors

This feature allows you to manage machine invocations as actors, which can send and receive events from other machines. The code sample shows how to spawn a child machine within a parent machine's context.

{"import { spawn, Machine } from 'xstate';\n\nconst parentMachine = Machine({\n  context: {\n    child: null\n  },\n  entry: ['spawnChild']\n}, {\n  actions: {\n    spawnChild: assign({\n      child: () => spawn(someMachine)\n    })\n  }\n});"}

Other packages similar to xstate

Readme

Source


XState logotype
Actor-based state management & orchestration for complex app logic. โ†’ Documentation

XState is a state management and orchestration solution for JavaScript and TypeScript apps. It has zero dependencies, and is useful for frontend and backend application logic.

It uses event-driven programming, state machines, statecharts, and the actor model to handle complex logic in predictable, robust, and visual ways. XState provides a powerful and flexible way to manage application and workflow state by allowing developers to model logic as actors and state machines.

โœจ Create state machines visually in Stately Studio โ†’ state.new


๐Ÿ“– Read the documentation

โžก๏ธ Create state machines with the Stately Editor

๐Ÿ–ฅ Download our VS Code extension

๐Ÿ“‘ Inspired by the SCXML specification

๐Ÿ’ฌ Chat on the Stately Discord Community

Templates

Get started by forking one of these templates on CodeSandbox:

Template

๐Ÿค– XState Template (CodeSandbox)

Open in StackBlitz

  • XState v5
  • TypeScript
  • No framework

โš›๏ธ XState + React Template (CodeSandbox)

Open in StackBlitz

๐Ÿ’š XState + Vue Template (CodeSandbox)

Open in StackBlitz

  • Vue
  • XState v5
  • TypeScript

๐Ÿงก XState + Svelte Template (CodeSandbox)

Open in StackBlitz

Super quick start

npm install xstate
import { createMachine, createActor, assign } from 'xstate';

// State machine
const toggleMachine = createMachine({
  id: 'toggle',
  initial: 'inactive',
  context: {
    count: 0
  },
  states: {
    inactive: {
      on: {
        TOGGLE: { target: 'active' }
      }
    },
    active: {
      entry: assign({ count: ({ context }) => context.count + 1 }),
      on: {
        TOGGLE: { target: 'inactive' }
      }
    }
  }
});

// Actor (instance of the machine logic, like a store)
const toggleActor = createActor(toggleMachine);
toggleActor.subscribe((state) => console.log(state.value, state.context));
toggleActor.start();
// => logs 'inactive', { count: 0 }

toggleActor.send({ type: 'TOGGLE' });
// => logs 'active', { count: 1 }

toggleActor.send({ type: 'TOGGLE' });
// => logs 'inactive', { count: 1 }

Stately Studio

  • Visually create, edit, and collaborate on state machines
  • Export to many formats, including XState v5
  • Test path & documentation autogeneration
  • Deploy to Stately Sky
  • Generate & modify machines with Stately AI
XState Viz

state.new

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:

Packages

PackageDescription
๐Ÿค– xstateCore finite state machine and statecharts library + interpreter
๐Ÿ“‰ @xstate/graphGraph traversal utilities for XState
โš›๏ธ @xstate/reactReact hooks and utilities for using XState in React applications
๐Ÿ’š @xstate/vueVue composition functions and utilities for using XState in Vue applications
๐ŸŽท @xstate/svelteSvelte utilities for using XState in Svelte applications
๐Ÿฅ @xstate/solidSolid hooks and utilities for using XState in Solid applications
โœ… @xstate/testModel-Based-Testing utilities (using XState) for testing any software
๐Ÿ” @xstate/inspectInspection utilities for XState

Finite State Machines

CodeStatechart
import { createMachine, createActor } from 'xstate';

const lightMachine = createMachine({
  id: 'light',
  initial: 'green',
  states: {
    green: {
      on: {
        TIMER: 'yellow'
      }
    },
    yellow: {
      on: {
        TIMER: 'red'
      }
    },
    red: {
      on: {
        TIMER: 'green'
      }
    }
  }
});

const actor = createActor(lightMachine);

actor.subscribe((state) => {
  console.log(state.value);
});

actor.start();
// logs 'green'

actor.send({ type: 'TIMER' });
// logs 'yellow'
CodeStatechart
Finite states
Open in Stately Studio

Hierarchical (Nested) State Machines

CodeStatechart
import { createMachine, createActor } 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 actor = createActor(lightMachine);

actor.subscribe((state) => {
  console.log(state.value);
});

actor.start();
// logs 'green'

actor.send({ type: 'TIMER' });
// logs 'yellow'

actor.send({ type: 'TIMER' });
// logs { red: 'walk' }

actor.send({ type: 'PED_TIMER' });
// logs { red: 'wait' }
Hierarchical states
Open in Stately Studio

Parallel State Machines

CodeStatechart
import { createMachine, createActor } from 'xstate';

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 actor = createActor(wordMachine);

actor.subscribe((state) => {
  console.log(state.value);
});

actor.start();
// logs {
//   bold: 'off',
//   italics: 'off',
//   underline: 'off',
//   list: 'none'
// }

actor.send({ type: 'TOGGLE_BOLD' });
// logs {
//   bold: 'on',
//   italics: 'off',
//   underline: 'off',
//   list: 'none'
// }

actor.send({ type: 'TOGGLE_ITALICS' });
// logs {
//   bold: 'on',
//   italics: 'on',
//   underline: 'off',
//   list: 'none'
// }
Parallel states
Open in Stately Studio

History States

CodeStatechart
import { createMachine, createActor } from 'xstate';

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 actor = createActor(paymentMachine);

actor.subscribe((state) => {
  console.log(state.value);
});

actor.start();
// logs {
//   value: { method: 'cash' },
// }

actor.send({ type: 'SWITCH_CHECK' });
// logs {
//   value: { method: 'check' },
// }

actor.send({ type: 'NEXT' });
// logs {
//   value: 'review',
// }

actor.send({ type: 'PREVIOUS' });
// logs {
//   value: { method: 'check' },
// }
History state
Open in Stately Studio

Sponsors

Special thanks to the sponsors who support this open-source project:

Transloadit Logo

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.

Keywords

FAQs

Last updated on 16 Apr 2024

Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with โšก๏ธ by Socket Inc