# State machines

Design each module as a state machine.

What it can see: only this page.

[Source on GitHub](https://github.com/mbsi-labs/skills/tree/main/rules/state-machines).

## The rule itself

Design each module as a state machine. Design each program as a state machine of modules.

Put the states of a module in one union type. Put its events in a different union type. Write one transition function. This function takes a state and an event. It gives the next state and the effects.

A surface is a CLI command, an HTTP route or a page. A surface sends events in and reads the state out. A surface does not make decisions.

Do not use classes. Do not use inheritance. Do not use methods that hide state.

Types do not reach across modules. When two modules need the same type, do one of two things:

1. Lift it out to a place both import from, if it is a fact about the domain (`Email`, `TicketId`, `Money`).
2. Merge the modules, if it is a state or event variant. The split was wrong, and they are one machine.

## Use it

Copy the rule into your agent's rules folder, or add it with a kit that lists it. Your agent reads it at the start of each session.

## Used by

- [builder](/kits/builder) (kit)

---

Published 2026-10-29. Web page: https://www.mackenziebowes.com/rules/state-machines Part of [Rules](https://www.mackenziebowes.com/rules).
