Backend domain workflows
Order lifecycles, payment sagas, incident management, KYC. The kind of state most teams scatter across switch event.Type and accumulate bugs around partial failure, retry, and idempotency.
Statekit is a typed statechart library for Go: hierarchical states, guards, actions, delayed and parallel transitions, with built-in visualization and lint. The same primitives serve backend domain workflows of every shape.
# Install
$ go get go.klarlabs.de/statekit
// A working machine in 10 lines
machine, _ := statekit.NewMachine[Order]("checkout").
WithInitial("cart").
State("cart").On("CHECKOUT").Target("processing").Done().
State("processing").On("PAID").Target("shipped").Done().
State("shipped").Final().Done().
Build()
interp := statekit.NewInterpreter(machine)
defer interp.Close()
interp.Start()
interp.Send(statekit.Event{Type: "CHECKOUT"})[C any] context, typed events, typed actions and guards. No interface{} casts at handler time.
Compound, parallel, history, and delayed transitions handle the workflows that flat FSM libraries can't model without manual bookkeeping.
Every machine renders to ASCII, Mermaid, interactive HTML, or TUI from one source. XState v5 export for Stately Studio round-trip editing.
lint.Lint(machine) catches unreachable states, dead ends, non-determinism, missing OnError on Invoke — at build time.
Inject a FakeClock to make timer-driven behavior reproducible. No time.Sleep flakes.
Order lifecycles, payment sagas, incident management, KYC (Stripe webhook saga template included) all share the same typed primitives.
| Concern | looplab/fsm | qmuntal/stateless | Statekit |
|---|---|---|---|
| Generics / typed context | open issue | open issue | first-class |
| Hierarchical states | — | partial (substates) | compound + parallel + history |
| Persistence (gob/JSON) | #40 unresolved | manual | Snapshot round-trips |
| Cancellation recovery | #115 stuck | — | OnError routing |
| Runaway prevention | — | #77 manual | Guard + attempt counter |
| Visualization | DOT | DOT | ASCII / Mermaid / HTML / TUI |
| Static analysis | — | — | lint with 9 rules |
Order lifecycles, payment sagas, incident management, KYC. The kind of state most teams scatter across switch event.Type and accumulate bugs around partial failure, retry, and idempotency.
Event sourcing replays a run deterministically, OnError routing bounds the blast radius, and snapshots give you audit-grade observability — the same typed primitives across every workflow.
See the incident lifecycle example →Drop it into your service. Or paste any Native JSON into the visualizer first.