v0.5.0 — Pythonic API & CLI Generator

State Machines for Python,
Done Right.

Define state machines in JSON or pure Python. Run them with async or sync interpreters. Generate production code with the CLI. Zero dependencies.

$ pip install xstate-statemachine
2,403 Tests Passing
6 Python Versions
0 Dependencies
5 CLI Templates

Why State Machines?

Replace brittle boolean flags and tangled conditionals with predictable, testable state logic.

Without State Machines
is_loading = True
has_error = False
is_authenticated = True
is_submitting = False

# What state are we actually in?
# Can we have is_loading AND has_error?
# Who resets is_submitting?
# 🤯 16 possible boolean combinations
With XState-StateMachine
machine = create_machine({
    "id": "app",
    "initial": "idle",
    "states": {
        "idle":       {"on": {"FETCH": "loading"}},
        "loading":    {"on": {"SUCCESS": "ready",
                              "ERROR": "error"}},
        "ready":      {"on": {"REFRESH": "loading"}},
        "error":      {"on": {"RETRY": "loading"}}
    }
})
# ✅ Exactly ONE state at a time. Always.

Everything You Need

A complete state machine runtime with no compromises. From simple toggles to complex multi-actor workflows.

🐍

Pythonic API

Define machines in pure Python with class-based, builder, or functional styles. No JSON required. Full type safety with decorators.

📋

XState Compatible

Load machines from XState JSON — the universal state machine format. Design visually in Stately.ai, run in Python.

Dual Interpreters

Async interpreter for web servers and event loops. Sync interpreter for scripts, CLI tools, and Django views.

🛠️

CLI Code Generator

Generate production-ready Python from XState JSON with 5 templates. Full type hints, docstrings, error handling, and logging.

🔌

Plugin System

Observe every event, transition, action, guard, and service with pluggable hooks. Built-in LoggingInspector included.

📸

Snapshots

Save and restore machine state with get_snapshot() and from_snapshot(). Perfect for persistence and crash recovery.

🏗️

Hierarchical & Parallel

Nested compound states for complex flows. Parallel regions for concurrent activity. Full XState v5 compatibility.

🎭

Actor Model

Spawn independent child machines from parent machines. Each actor has its own state, context, and lifecycle.

⏱️

Delayed Transitions

Timer-based after transitions for timeouts, polling, and auto-progression. Multiple timers per state supported.

Four Ways to Define Machines

Pick the style that matches your team. All compile to the same runtime.

from xstate_statemachine import (
    State, StateMachine, SyncInterpreter, action, guard
)

class TrafficLight(StateMachine):
    machine_id = "trafficLight"

    # States
    green  = State("green",  initial=True)
    yellow = State("yellow")
    red    = State("red")

    # Transitions
    slow_down = green.to(yellow, event="TIMER")
    stop      = yellow.to(red,   event="TIMER")
    go        = red.to(green,    event="TIMER")

    @action
    def log_change(self, interpreter, context, event, action_def):
        print(f"Light: {interpreter.active_state_ids}")

# Run it
machine = TrafficLight.create_machine()
interp = SyncInterpreter(machine).start()
interp.send("TIMER")  # green → yellow
interp.send("TIMER")  # yellow → red
interp.stop()
from xstate_statemachine import MachineBuilder, SyncInterpreter

machine = (
    MachineBuilder("trafficLight")
    .state("green",  initial=True)
    .state("yellow")
    .state("red")
    .transition("green",  "TIMER", "yellow")
    .transition("yellow", "TIMER", "red")
    .transition("red",    "TIMER", "green")
    .build()
)

interp = SyncInterpreter(machine).start()
interp.send("TIMER")  # green → yellow
interp.send("TIMER")  # yellow → red
interp.stop()
from xstate_statemachine import State, build_machine, SyncInterpreter

green  = State("green",  initial=True)
yellow = State("yellow")
red    = State("red")

green.to(yellow, event="TIMER")
yellow.to(red,   event="TIMER")
red.to(green,    event="TIMER")

machine = build_machine(
    id="trafficLight",
    states=[green, yellow, red],
)

interp = SyncInterpreter(machine).start()
interp.send("TIMER")  # green → yellow
interp.send("TIMER")  # yellow → red
interp.stop()
from xstate_statemachine import create_machine, SyncInterpreter

config = {
    "id": "trafficLight",
    "initial": "green",
    "states": {
        "green":  {"on": {"TIMER": "yellow"}},
        "yellow": {"on": {"TIMER": "red"}},
        "red":    {"on": {"TIMER": "green"}},
    }
}

machine = create_machine(config)
interp = SyncInterpreter(machine).start()
interp.send("TIMER")  # green → yellow
interp.send("TIMER")  # yellow → red
interp.stop()

Built for Real-World Use Cases

From simple toggles to complex enterprise workflows.

🛒

E-Commerce

Cart → checkout → payment → shipping → delivered. Never lose an order to an impossible state.

🔒

Authentication

Login flows, MFA, session management, token refresh. Every auth state transition is explicit and auditable.

📝

Form Wizards

Multi-step forms with validation, back navigation, and conditional branching. Guards ensure data integrity.

🔄

CI/CD Pipelines

Build → test → deploy → verify. With invoke for async steps, guards for approval gates, and retry on failure.

🎮

Game Logic

Character states, turn management, quest progression. Parallel states for simultaneous systems.

🤖

IoT & Devices

Device lifecycle, connection management, sensor monitoring. Delayed transitions for timeouts and heartbeats.

5 CLI Templates

Generate production-ready Python from any XState JSON config.

pythonic-class

Class-Based

StateMachine subclass with @action, @guard, @service decorators. OOP at its best.

pythonic-builder

Builder Pattern

Fluent MachineBuilder API for dynamic, programmatic construction.

pythonic-functional

Functional

Simple build_machine() with explicit state and transition definitions.

class-json

Class + JSON

OOP logic class bound to JSON config loaded at runtime.

function-json

Functions + JSON

Module-level functions with LogicLoader auto-discovery.

How It Compares

The most comprehensive Python state machine library available.

Feature XState-StateMachine transitions python-statemachine sismic
Hierarchical States⚠️
Parallel States
Delayed Transitions
Invoke / Services
Actor Model
XState JSON Compat
Pythonic API
Async + Sync
CLI Code Generator
Plugin System
Snapshot/Restore
Diagram Export
Zero Dependencies

Design → Generate → Run

Seamless workflow from visual design to production Python code.

1

Design

Design your machine visually at stately.ai or write XState JSON by hand.

2

Generate

Run xsm gt machine.json --template pythonic-class to generate Python code.

3

Implement

Fill in action, guard, and service stubs with your business logic.

4

Run

Execute with SyncInterpreter or Interpreter. Attach plugins for observability.

Ready to Tame Complexity?

Build reliable, predictable Python applications with formal state management.

Read the Guide Quick Start (5 min) View on GitHub