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
Replace brittle boolean flags and tangled conditionals with predictable, testable state logic.
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
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.
A complete state machine runtime with no compromises. From simple toggles to complex multi-actor workflows.
Define machines in pure Python with class-based, builder, or functional styles. No JSON required. Full type safety with decorators.
Load machines from XState JSON — the universal state machine format. Design visually in Stately.ai, run in Python.
Async interpreter for web servers and event loops. Sync interpreter for scripts, CLI tools, and Django views.
Generate production-ready Python from XState JSON with 5 templates. Full type hints, docstrings, error handling, and logging.
Observe every event, transition, action, guard, and service with pluggable hooks. Built-in LoggingInspector included.
Save and restore machine state with get_snapshot() and from_snapshot(). Perfect for persistence and crash recovery.
Nested compound states for complex flows. Parallel regions for concurrent activity. Full XState v5 compatibility.
Spawn independent child machines from parent machines. Each actor has its own state, context, and lifecycle.
Timer-based after transitions for timeouts, polling, and auto-progression. Multiple timers per state supported.
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()
From simple toggles to complex enterprise workflows.
Cart → checkout → payment → shipping → delivered. Never lose an order to an impossible state.
Login flows, MFA, session management, token refresh. Every auth state transition is explicit and auditable.
Multi-step forms with validation, back navigation, and conditional branching. Guards ensure data integrity.
Build → test → deploy → verify. With invoke for async steps, guards for approval gates, and retry on failure.
Character states, turn management, quest progression. Parallel states for simultaneous systems.
Device lifecycle, connection management, sensor monitoring. Delayed transitions for timeouts and heartbeats.
Generate production-ready Python from any XState JSON config.
StateMachine subclass with @action, @guard, @service decorators. OOP at its best.
pythonic-builderFluent MachineBuilder API for dynamic, programmatic construction.
pythonic-functionalSimple build_machine() with explicit state and transition definitions.
class-jsonOOP logic class bound to JSON config loaded at runtime.
function-jsonModule-level functions with LogicLoader auto-discovery.
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 | ✅ | ❌ | ❌ | ❌ |
Seamless workflow from visual design to production Python code.
Run xsm gt machine.json --template pythonic-class to generate Python code.
Fill in action, guard, and service stubs with your business logic.
Execute with SyncInterpreter or Interpreter. Attach plugins for observability.
Build reliable, predictable Python applications with formal state management.