Run your XState / Stately.ai JSON unmodified, or define machines in pure Python. Async and sync interpreters. The CLI generates typed code and proves it rebuilds your machine before writing it. 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.
The generator compiles its own output, builds the machine, and compares it against your JSON before writing. A mismatch exits non-zero and writes nothing. Add --check to catch drift in CI.
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.
actionErrorPolicy: "rollback" restores configuration and context after a raising action, onUnhandled catches events nothing handles, strict mode raises on undeclared events at the call site, and a bounded inbox with OverflowPolicy gives you backpressure instead of unbounded memory.
Inject a Clock — RealClock in production, SimulatedClock in tests. Advance virtual time deterministically to fire after timers and delayed sends without sleeping, on either interpreter.
send(wait=True) returns a Receipt the moment the macrostep for that event has run — no polling for state to settle. priority=True jumps the inbox for decisions that cannot wait behind routine traffic.
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,
on={"TIMER": "yellow"})
yellow = State("yellow", on={"TIMER": "red"})
red = State("red", on={"TIMER": "green"})
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 | ✅ | ❌ | ❌ | ❌ |
Same machine shape, each library through its own idiomatic API. Higher is better; bold is fastest in the row.
| Scenario | XState-StateMachine | transitions | python-statemachine | sismic |
|---|---|---|---|---|
| Flat toggle events/s | 50,033 | 98,196 | 9,575 | 10,965 |
| Guard + action events/s | 64,851 | 77,860 | 7,604 | 10,009 |
| 3-level nested events/s | 20,923 | 6,609 | 2,619 | 3,659 |
| Parallel regions events/s | 38,314 | 4,891 | 2,721 | 4,595 |
| Delayed transitions timers/s | 7,245 | 77 | 2,843 | 4,332 |
| 1,000 instances instances/s | 25,726 | 23,765 | 2,817 | 5,781 |
| Construction machines/s | 6,496 | 7,357 | 866 | 182 |
| Native asyncio events/s | 21,985 | 34,739 | 5,389 | — |
transitions is faster on flat machines because it is a transition table, not a statechart
engine — no configuration set, no entry/exit ordering, no internal queue. The moment states nest or run in
parallel, that algorithm is what the others have to emulate, and XState-StateMachine is 3–8× faster
than every library that actually implements statecharts. Python 3.14, median of 7 runs, GC disabled, setup excluded.
Reproduce with benchmarks/competitors/run.py; method and caveats in
Production Characteristics.
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.