---
name: State Diagram
status: draft
description: PROCESS/STRUCTURE family. The state machine — the distinct states a system can be in, drawn as nodes, with event-labeled arrows for every legal transition between them.
sources:
  - title: "Harel, David (1987), \"Statecharts: A Visual Formalism for Complex Systems\", Science of Computer Programming 8(3)"
    url: https://doi.org/10.1016/0167-6423%2887%2990035-9
  - title: "Fowler, Martin (1997), UML Distilled: Applying the Standard Object Modeling Language"
    url: https://openlibrary.org/works/OL463953W
---

# State Diagram

## Why it matters

A state diagram — also called a state machine — answers a question that trips up most attempts to describe how a system behaves: not "what steps does it run through?" but "what *situations* can it be in, and what moves it from one to the next?" It draws each distinct situation the system can occupy as a labeled box (a state), and each legal move between situations as an arrow (a transition), with every arrow tagged by the event that fires it. A filled dot marks where the system starts. The point of the picture is to make the legal states and the allowed moves between them explicit — and, just as sharply, to expose the moves that are *impossible*.

For example: a checkout flow keeps double-charging customers. The bug report says "the pay button fires twice." Sketched as a flowchart of steps, nothing looks wrong — pay, then confirm, then receipt. Drawn as a state machine, the defect is obvious: there is a transition arrow out of *Paid* back to *Awaiting Payment* on a second click, when *Paid* should have **no** pay-event transition at all. The flow hid the problem because it described what *usually* happens; the state diagram caught it because it described what is *allowed* to happen, and that arrow should never have existed.

- **What it shows.** Every distinct state a system can be in, and every legal transition between them — each transition labeled with the event that triggers it (plus an optional guard and action).
- **When to reach for it.** A system whose response to an event depends on the state it's currently in — an order lifecycle, a UI workflow, a network protocol — where the same input means different things in different states.
- **How to read it.** Start at the filled dot (the start state) and follow events: in this state, *this* event takes you *there*; that same event over here does nothing. The arrows are the grammar of legal moves.
- **What you'd miss without it.** The illegal transitions — the moves that should be impossible. A list of states tells you where the system *can* be; only the arrows tell you what it must *refuse* to do.
- **Where it misleads.** It models discrete, event-driven configuration changes, so it hides continuous quantities, feedback over time, and the *order* of messages between parties — and a state explosion (too many states) turns the picture into an unreadable maze.

## How to read it

Picture a handful of rounded boxes connected by labeled arrows. Each **box is a state** — a distinct, named situation the system can rest in, written as a condition rather than an action (*Idle*, *Ready*, *Dispensing*, *Awaiting Payment*, not *dispense* or *wait*). A small **filled dot** with an arrow into one box marks the **start state**: where the system is the moment it comes alive. A dot inside a ring marks a **final state**, where the system terminates. Every other arrow is a **transition**, and the system can only ever be in exactly one state at a time.

You read it by following events. Take a vending machine. The start dot points to *Idle*. From *Idle*, a `coin` event → *Ready*; from *Ready*, a `select` event → *Dispensing*; from *Dispensing*, a `done` event → back to *Idle*. The label on each arrow is the **event** — the trigger that fires the move (a user action, a timer expiring, a message arriving). And the negative space carries just as much meaning: there is no `select` arrow out of *Idle*, which is precisely how the diagram says "you cannot select before paying." The states enumerate where the system can be; the arrows enumerate every move it's permitted to make; and the absence of an arrow is a promise about what it will refuse.

Two refinements make a transition more precise. A **guard** is a condition in square brackets that must be true for the transition to fire — the same event can lead to different states depending on the guard (`coin [amount < price]` keeps you in *Ready*; `coin [amount >= price]` moves you on). An **action**, written after a slash, is a side effect the transition performs as it fires (`select / dispense_item`). For systems too complex for a flat picture, **David Harel's statecharts** add two more tools: **nesting** (a state can contain its own sub-state-machine, so *Active* might hold *Browsing* and *CheckingOut* inside it) and **concurrency** (a system can be in two independent states at once, drawn as parallel regions) — the extensions that let a state diagram scale from a textbook toy to the specification of a real application.

## When to use it

The state diagram belongs to the **PROCESS/STRUCTURE family** of diagrams — the ones that map how a system is organized and how it moves — and within it, the state diagram is the *stateful-behavior* tool: the one you reach for when an object or system has a finite set of states and changes between them in response to events. Reach for it to model an **order lifecycle** (cart → placed → paid → fulfilled → cancelled), a **UI workflow** (a multi-step wizard, a modal that can be open, dirty, or saving), or a **protocol** (a TCP connection that is *Listen*, *Established*, or *Closing*). The test is simple: if the same event has to mean different things depending on where the system already is, you need states.

Knowing the three nearest relatives is how you pick the right picture:

- A **Flowchart** models *procedural steps* — the sequence of operations in a single linear process — not states. Use it when the question is "what happens next?", not "what situation are we in?" A flowchart of a lifecycle quietly loses the back-transitions and the state-dependent behavior a state diagram is built to capture.
- A **Sequence Diagram** models *interactions over time* — the messages exchanged between several participants, in order. Use it when the question is who-tells-whom-what-when; the state diagram is what's happening *inside* one of those participants.
- A **Causal Loop Diagram** models *feedback* — variables pushing on each other in reinforcing and balancing loops over time. Use it for continuous system dynamics; the state diagram is for discrete, event-triggered switches between named configurations.

Reach for a state diagram when the system is stateful, the states are finite and namable, and the transitions are driven by observable events. Skip it when the process is a single linear flow (use a flowchart), when the interesting thing is the ordering of messages between actors (use a sequence diagram), or when the dynamics are continuous feedback rather than discrete states (use a causal loop diagram).

## How Ora builds it

Ora produces a state diagram from a **semantic spec** — a structured description of the **states** (each a named configuration, optionally with entry and exit actions), the **transitions** between them (each carrying the triggering event, an optional guard condition in brackets, and an optional action after a slash), the explicit **initial state**, and one or more **final states**. Where a system is too rich for a flat machine, the spec supports Harel's **nesting** (sub-state-machines inside a state) and **concurrency** (parallel regions). That spec is then rendered — typically as a Mermaid `stateDiagram` or a PlantUML state machine — with an outline view and alt-text for screen readers, since arrows and boxes alone are not accessible.

The diagram is the visual face of Ora's **system- and behavior-design** work: when you ask "what are the states and transitions of this lifecycle — draw the state machine," that operation enumerates the legal states, fires each event to find where it leads, and surfaces the transitions that should *not* exist. Drafting the state machine before the data model pays off directly: the states tell you what values a status column must hold, and the transitions tell you which operations the system must expose.

The technique descends from the **finite state machines** of automata theory (the deterministic and nondeterministic automata at the foundation of computer science), was extended for real-world complexity by **David Harel**, whose 1987 paper *Statecharts: A Visual Formalism for Complex Systems* added the hierarchy, concurrency, and history that scaled state diagrams up to industrial systems, and was then standardized as the **UML state machine diagram**, which adopts Harel's statechart vocabulary almost wholesale (Fowler, *UML Distilled*). The form is now foundational in embedded and real-time engineering, in protocol specification (the state machines in the RFCs for TCP and TLS), and increasingly in UI engineering, where state-machine libraries formalize what interface developers had long been doing by hand.

## Related

- **Sequence Diagram** — the PROCESS family member for *interactions*: the ordered messages exchanged between participants over time, where the state diagram shows the behavior inside a single participant.
- **Flowchart** — the family member for *procedural steps*: a single linear process of operations and decisions, where the state diagram shows states and the events that switch between them.
- **C4 Architecture Diagram** — the structural counterpart: the static arrangement of a system's parts, where the state diagram shows one part's dynamic behavior over its lifetime.
- **Causal Loop Diagram** — the dynamics counterpart: continuous feedback loops and delays, where the state diagram shows discrete, event-triggered transitions between named states.

## Sources

- [Harel, David (1987), "Statecharts: A Visual Formalism for Complex Systems", Science of Computer Programming 8(3)](https://doi.org/10.1016/0167-6423%2887%2990035-9)
- [Fowler, Martin (1997), UML Distilled: Applying the Standard Object Modeling Language](https://openlibrary.org/works/OL463953W)
