RoboCitrus Logo
When your Flutter widget needs a state machine (AI-generated cover image) Cover image: AI-generated

When your Flutter widget needs a state machine

Published:
1 min read

A talk that starts with fighter jets and the moon landing

The talk was titled "From Fighter Jets to Flutter" and was really about state machines and statecharts in Flutter UI development. The speaker said right at the start that there would be no fighting today. Instead, we went to the moon.

I liked the opening because it answers a question I ask myself a lot: why do my UIs get messy at some point, even though every single piece looks simple?

The history, short version

Margaret Hamilton was part of the team that wrote the software for the Apollo mission. When that software crashes, you don't get an error message, you get a catastrophe. No hot reload either. One anecdote from the talk: shortly before landing, the software noticed CPU usage climbing and stopped certain code from running. Otherwise it would have crashed.

In 1977 Hamilton and colleagues founded a company called Higher Order Software. The idea was a new way to describe critical software, declaratively and with a strict syntax. If something can't be expressed in that syntax, it counts as wrong. They used function trees for this, graphs that show what the software does.

David Harel was doing his PhD at MIT at the time and spent a summer with the team. He asked how you actually verify such software. He wasn't convinced by the "it's all in the syntax" answer. But he liked the graphical approach.

Later he was approached for a confidential project in Israel. It was software for fighter jets. The engineers knew their own parts very well but couldn't describe the whole system. Questions were answered with pointers to hundreds of pages of manuals. While asking and listening, Harel noticed he had started drawing diagrams. And that people understood those diagrams better than a pile of text. That's how statecharts came about.

A note on sources: my recording is unclear on the year of the fighter jet work, so I'm not naming one.

State machine vs. statechart

A state machine is simple. You have a state, an event comes in, and you end up in another state. That's it.

For complex systems that isn't enough. Harel extended the concept into statecharts. The key point from the talk: states can contain other states. You nest them. That lets you describe much more complex behavior without the diagram blowing up.

The example: cards on a board

The speaker works on a tool that converts designs into Flutter code. There he ran into complex interactions: dragging handles, resizing, moving. At some point he couldn't describe them anymore. Then he found Harel.

For the demo he built a small note-taking app. Cards sit on a board, you can drag them and resize them at the corners. The interesting part: while you resize a card at a corner, you press the spacebar. Now you move the whole card. Release the key and you're resizing again. Anyone who has used a design tool knows this behavior.

The statechart for it consists of:

  • an idle state where nothing happens,
  • a changing state that contains the substates resizing and moving,
  • a canceled state for when the action is discarded.

States and events can carry data. When resizing, the app needs to know which corner is being dragged, for example. The "resize" event brings that information along. This makes the description a lot simpler.

The speaker implemented it with his own Dart package called Harel, named after David Harel. There's also a companion tool, the Harel Inspector.

The inspector, and why it convinced me

The inspector connects to the running app and shows the statechart as a diagram. You drag a corner, and the active state lights up. Press the spacebar and you see the switch from resizing to moving live.

Two more things I find practical:

  • An event log that lists all events in order. You can read bugs off it.
  • Clicking a state jumps straight to the matching code in the IDE. In big codebases that saves search time.

The speaker's point, roughly: without a framework like this you write print statements by hand. With a state machine you get observability for free. With a GestureDetector plus a few booleans, you'd have to build it again for every app.

AI writes the code, you still have to understand it

This part stuck with me most. The speaker asked the audience who reads the code an LLM writes. Who reads more than half? Who reads all of it? His point: we simply don't have the time to review every line.

The demo app itself was written by an LLM. He gave it the package and a skill and told it to build the app with it. He still has to understand what's going on. A diagram you watch running next to the app is faster for that than reading logic. And since it's visible, your agent can look at it too.

That matches what I wrote in When AI writes your Flutter app and Marionette MCP: AI agents testing Flutter apps: the better you can see what the app does, the better you can control AI code.

When does a state machine pay off?

The speaker was clear: not for every piece of UI. His rule of thumb is a question: is my widget starting to look like an app?

His examples:

  • A rich text editor with bold, italic, block types and drag and drop is no longer a widget, it's an app.
  • An Instagram-style story viewer: swipe up shows reactions, swipe down hides them, a short press discards them.

You often don't plan for interactions like these at the start. But users expect them because they know Instagram or TikTok. And when you have to build them, that's the moment for a state machine.

He also said you sometimes don't need all the overhead of states and events. Then normal architecture is enough.

My take: state machines and Bloc

From here on it's my own opinion, not the speaker's. He didn't compare Bloc or Cubit in the talk.

I use Bloc and Cubit in most of my apps, the reasons are in Flutter State Management 2026. For screens with data, loading, error and success it fits very well. A Cubit with a clean list of states is basically a small state machine already.

What Bloc doesn't cover is the fine detail inside a widget. If a single card switches between resizing, moving and canceling, with a key press in the middle, I don't create a Bloc for that. There I'd now reach for a real state machine instead of stacking booleans in a StatefulWidget.

The way I see it: Bloc or Cubit for app state, a state machine for complex interactions inside one widget. Whether I'll use the Harel package myself, I can't say yet. I haven't tried it. I do like the idea of getting observability for free.

Conclusion

The talk gave me a simple criterion: if your widget looks like an app, you need more than booleans. Statecharts have been proven for decades, from fighter jets to design tools. And in the age of AI-generated code, a diagram you can watch live is a pretty practical safety net.

For most screens, architecture is enough. For the few interaction-heavy special cases, state machines are worth a look.

More on my view of the framework is in Why I love Flutter. And how AI changes development overall is in AI in app development.


Frequently asked questions (FAQ)


This article was inspired by the talk "State Machines, State Charts, and Flutter UI Development" (From Fighter Jets to Flutter) at FlutterCon 2026.

Let's Connect! 🚀

Ready for your next project?
Let's get started!

Let's get started

Tell me about your vision – just drop me an email or use the contact form. Let's plan your digital success together! 💪