Why Mechanoid
ZIO apps already excel at typed effects, composition, and resource safety. Mechanoid applies those same values to the control plane of your domain: the finite set of states a workflow can be in, and the events that move it.
Why finite state machines
Many product workflows are graphs whether you name them or not: checkout, document review,
payment capture, service health. Allowed moves, cancellations, and deadlines are part of the
domain. When that graph stays implicit (a fold of flags and if branches), the picture lives
only in someone's head:
Making the graph explicit pays off when product and engineering need a shared picture of allowed moves, when compile-time checks should catch duplicate or missing transitions, and when persistence, timeouts, and locking should be optional layers, not a rewrite.
Why Mechanoid
Mechanoid is the typed FSM layer that sits inside the ZIO application you already like:
States and events are Scala 3 enums or sealed traits (
derives Finite)Transitions are ZIO effects with your environment and error channel
Assemblies are validated at compile time (duplicates, overrides, produced-event types)
Runtime plugs into the same layer style you already use for services and stores
What is special is the DSL and composability: infix transitions, hierarchical all[T],
reusable fragments with ++ / assemblyAll, and aspects like timeouts and intentional
overrides. It is not a generic actor FSM, and it is not a heavyweight workflow engine.
The production ladder
Grow capabilities without changing the machine definition. Overview walks the same ladder with a first runnable machine.
| Rung | What you add | When |
|---|---|---|
| In-memory | machine.start | Local logic, tests, simple services |
| Persistence | EventStore + FSMRuntime | Survive restarts, audit the history |
| Durable timeouts | TimeoutStore + sweeper | Deadlines that outlive a node |
| Distributed | FSMInstanceLock / leader election | Multi-node, high contention |
Docs that cannot drift
This site is built from Specular DocSpecs: every example asserts under zio-test when the site is built. Machines are rendered with mermoid from the same definitions you run, so the picture, the suite, and the API stay aligned.
Continue with Quick Start, or dig into Defining FSMs for the DSL.