or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

actions.mdactors.mdgraph-utilities.mdguards.mdindex.mdstate-machines.md
tile.json

tessl/npm-xstate

Actor-based state management & orchestration for complex app logic.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/xstate@5.21.x

To install, run

npx @tessl/cli install tessl/npm-xstate@5.21.0

index.mddocs/

XState

XState is a comprehensive state management and orchestration library for JavaScript and TypeScript applications that enables developers to model complex application logic using finite state machines, statecharts, and the actor model. Built with zero dependencies, it provides predictable, robust, and visual ways to handle application workflow state through event-driven programming paradigms.

Package Information

  • Package Name: xstate
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install xstate

Core Imports

import { createMachine, createActor, setup } from "xstate";

For CommonJS:

const { createMachine, createActor, setup } = require("xstate");

Entry point specific imports:

// Actions
import { assign, raise, sendTo, spawnChild } from "xstate/actions";

// Actors  
import { fromCallback, fromPromise, fromObservable } from "xstate/actors";

// Guards
import { and, or, not, stateIn } from "xstate/guards";

// Graph utilities
import { createTestModel, getShortestPaths } from "xstate/graph";

// Development tools
import { devToolsAdapter } from "xstate/dev";

Basic Usage

import { createMachine, createActor, assign } from "xstate";

// Define a state machine
const toggleMachine = createMachine({
  id: "toggle",
  initial: "inactive", 
  context: { count: 0 },
  states: {
    inactive: {
      on: {
        TOGGLE: {
          target: "active",
          actions: assign({ count: ({ context }) => context.count + 1 })
        }
      }
    },
    active: {
      on: {
        TOGGLE: {
          target: "inactive", 
          actions: assign({ count: ({ context }) => context.count + 1 })
        }
      }
    }
  }
});

// Create and start an actor
const actor = createActor(toggleMachine);
actor.start();

// Subscribe to state changes
actor.subscribe((snapshot) => {
  console.log("State:", snapshot.value);
  console.log("Context:", snapshot.context);
});

// Send events
actor.send({ type: "TOGGLE" });

Architecture

XState is built around several key architectural patterns:

  • State Machines: Finite state machines and statecharts for modeling application logic with explicit states and transitions
  • Actor Model: Self-contained actors that encapsulate state and behavior, communicating through message passing
  • Event-Driven Programming: All state changes happen through discrete events, ensuring predictable state transitions
  • Type Safety: Full TypeScript integration with static type checking for states, events, context, and actions
  • Zero Dependencies: Self-contained library with no external runtime dependencies

Capabilities

State Machine Creation

Core functionality for creating and configuring state machines with states, transitions, guards, and actions.

function createMachine<
  TContext,
  TEvent extends { type: string },
  TActor = any,
  TAction = any,
  TGuard = any,
  TDelay = string,
  TTag = string,
  TInput = any,
  TOutput = any
>(
  config: MachineConfig<TContext, TEvent, TActor, TAction, TGuard, TDelay, TTag, TInput, TOutput>
): StateMachine<TContext, TEvent, TActor, TAction, TGuard, TDelay, TTag, TInput, TOutput>;

function setup<T extends SetupTypes>(
  implementations: T
): {
  createMachine<TConfig extends MachineConfig<any, any>>(
    config: TConfig
  ): StateMachine</* type parameters */>;
};

State Machines

Actor Management

Actor system for creating, managing, and communicating with stateful actors that run state machines and other logic.

function createActor<TLogic extends AnyActorLogic>(
  logic: TLogic,
  options?: ActorOptions<TLogic>
): Actor<TLogic>;

class Actor<TLogic extends AnyActorLogic> {
  start(): void;
  stop(): void;
  send(event: EventFromLogic<TLogic>): void;
  subscribe(observer: Observer<SnapshotFrom<TLogic>>): Subscription;
  getSnapshot(): SnapshotFrom<TLogic>;
}

Actors

Built-in Actions

Comprehensive set of built-in actions for context assignment, event handling, actor communication, and lifecycle management.

function assign<TContext, TExpressionEvent extends { type: string }>(
  assignment: Assigner<TContext, TExpressionEvent> | PartialAssigner<TContext, TExpressionEvent>
): ActionFunction<TContext, TExpressionEvent>;

function raise<TEvent extends { type: string }>(
  eventOrExpr: TEvent | ((args: ActionArgs<any, any>) => TEvent),
  options?: { id?: string; delay?: number }
): ActionFunction<any, any>;

function sendTo<TTargetActor extends AnyActorRef, TEvent extends { type: string }>(
  actor: TTargetActor | string | ((args: ActionArgs<any, any>) => TTargetActor | string),
  eventOrExpr: TEvent | ((args: ActionArgs<any, any>) => TEvent),
  options?: { id?: string; delay?: number }
): ActionFunction<any, any>;

Actions

Guard Predicates

Guard functions and combinators for conditional logic in state machine transitions and actions.

function and<TContext, TExpressionEvent extends { type: string }>(
  guards: Guard<TContext, TExpressionEvent>[]
): GuardPredicate<TContext, TExpressionEvent>;

function or<TContext, TExpressionEvent extends { type: string }>(
  guards: Guard<TContext, TExpressionEvent>[]
): GuardPredicate<TContext, TExpressionEvent>;

function not<TContext, TExpressionEvent extends { type: string }>(
  guard: Guard<TContext, TExpressionEvent>
): GuardPredicate<TContext, TExpressionEvent>;

function stateIn<TContext, TExpressionEvent extends { type: string }>(
  stateValue: StateValue
): GuardPredicate<TContext, TExpressionEvent>;

Guards

Graph Utilities

Testing, visualization, and analysis tools for state machines including model-based testing and path generation.

function createTestModel<TLogic extends AnyActorLogic>(
  logic: TLogic,
  options?: TestModelOptions
): TestModel<TLogic>;

class TestModel<TLogic extends AnyActorLogic> {
  getShortestPaths(options?: TraversalOptions): StatePath[];
  getSimplePaths(options?: TraversalOptions): StatePath[]; 
  testPath(path: TestPath, params: TestParam): void;
}

function getShortestPaths<TLogic extends AnyActorLogic>(
  logic: TLogic,
  options?: TraversalOptions  
): StatePath[];

Graph Utilities

Core Types

interface MachineConfig<
  TContext,
  TEvent extends { type: string },
  TActor = any,
  TAction = any,
  TGuard = any,
  TDelay = string,
  TTag = string,
  TInput = any,
  TOutput = any
> {
  id?: string;
  initial?: string | InitialTransitionConfig<TContext, TEvent>;
  context?: TContext | ContextFactory<TContext, TEvent>;
  states?: StatesConfig<TContext, TEvent, TActor, TAction, TGuard, TDelay, TTag>;
  on?: TransitionsConfig<TContext, TEvent, TAction, TGuard, TDelay>;
  entry?: Actions<TContext, TEvent, TAction>;
  exit?: Actions<TContext, TEvent, TAction>;
  after?: DelayedTransitions<TContext, TEvent, TAction, TGuard, TDelay>;
  always?: TransitionConfigOrTarget<TContext, TEvent, TAction, TGuard>[];
  invoke?: InvokeConfig<TContext, TEvent, TActor>[];
  onDone?: TransitionConfigOrTarget<TContext, DoneStateEvent<TOutput>, TAction, TGuard>[];
  tags?: TTag[];
  description?: string;
  type?: "atomic" | "compound" | "parallel" | "final" | "history";
  output?: Mapper<TContext, TEvent, TOutput> | TOutput;
  meta?: MetaObject;
}

interface StateMachine<
  TContext,
  TEvent extends { type: string },
  TActor = any,
  TAction = any,
  TGuard = any,
  TDelay = string,
  TTag = string,
  TInput = any,
  TOutput = any
> {
  id: string;
  config: MachineConfig<TContext, TEvent, TActor, TAction, TGuard, TDelay, TTag, TInput, TOutput>;
  implementations: MachineImplementations<TContext, TEvent, TActor, TAction, TGuard, TDelay>;
  getInitialSnapshot(input?: TInput): MachineSnapshot<TContext, TEvent, TActor, TAction, TGuard, TDelay, TTag>;
  transition(snapshot: MachineSnapshot<any, any>, event: TEvent): MachineSnapshot<TContext, TEvent, TActor, TAction, TGuard, TDelay, TTag>;
}

interface MachineSnapshot<
  TContext,
  TEvent extends { type: string },
  TActor = any,
  TAction = any,
  TGuard = any,
  TDelay = string,
  TTag = string
> extends Snapshot<any> {
  context: TContext;
  value: StateValue;
  machine: StateMachine<TContext, TEvent, TActor, TAction, TGuard, TDelay, TTag>;
  matches(stateValue: StateValue): boolean;
  hasTag(tag: TTag): boolean;
  can(event: TEvent): boolean;
}

interface ActorRef<TSnapshot extends Snapshot<unknown>, TEvent extends { type: string }> {
  id: string;
  send(event: TEvent): void;
  subscribe(observer: Observer<TSnapshot>): Subscription;
  getSnapshot(): TSnapshot;
  getPersistedSnapshot(): Snapshot<unknown>;
}

type StateValue = string | { [key: string]: StateValue };

interface EventObject {
  type: string;
}

interface AnyEventObject extends EventObject {
  [key: string]: any;
}

type MachineContext = Record<string, any>;

interface MetaObject {
  [key: string]: any;
}

Type Extraction Utilities

type InputFrom<T> = T extends StateMachine<any, any, any, any, any, any, any, infer TInput, any> ? TInput : never;
type OutputFrom<T> = T extends StateMachine<any, any, any, any, any, any, any, any, infer TOutput> ? TOutput : never;
type StateFrom<T> = T extends StateMachine<infer TContext, infer TEvent, infer TActor, infer TAction, infer TGuard, infer TDelay, infer TTag, any, any> 
  ? MachineSnapshot<TContext, TEvent, TActor, TAction, TGuard, TDelay, TTag> : never;
type ContextFrom<T> = T extends StateMachine<infer TContext, any, any, any, any, any, any, any, any> ? TContext : never;
type EventFrom<T> = T extends StateMachine<any, infer TEvent, any, any, any, any, any, any, any> ? TEvent : never;
type SnapshotFrom<T> = T extends ActorLogic<infer TSnapshot, any, any, any, any> ? TSnapshot : never;