Glad to see statecharts still getting attention!<p>I created XState, a JS/TS library for authoring, executing, and visualizing state machines/statecharts: <a href="https://github.com/statelyai/xstate" rel="nofollow">https://github.com/statelyai/xstate</a><p>I've been working on it for 10+ years. The main thing I've learned is that statecharts are most valuable when they're treated as executable behavior, not just documentation.<p>That doesn't mean you need to use them everywhere or model everything with them. They're most useful when you have behavior where the answer to "what happens next?" depends on both the current state & the event. A statechart can act as an oracle for questions like: "Given I'm in this state, when this event happens, what is the next state, and what effects should run?"<p>I'm close to releasing an alpha of the next major version of XState, focused on better ergonomics, type safety, and composability, as well as a new visualizer/editor.<p>There's also an open-source basic statechart visualizer here: <a href="https://sketch.stately.ai" rel="nofollow">https://sketch.stately.ai</a><p>For the formal/spec side, SCXML is worth reading: <a href="https://www.w3.org/TR/scxml" rel="nofollow">https://www.w3.org/TR/scxml</a><p>Also worth reading the original paper by David Harel: <a href="https://www.weizmann.ac.il/math/harel/sites/math.harel/files/users/user50/Statecharts.pdf" rel="nofollow">https://www.weizmann.ac.il/math/harel/sites/math.harel/files...</a>
You were the reason I first discovered state machines!<p>This was a talk I gave at Laracon that was my stab at distilling my thinking about State Machines, State Charts etc.<p><a href="https://www.youtube.com/watch?v=1A1xFtlDyzU" rel="nofollow">https://www.youtube.com/watch?v=1A1xFtlDyzU</a>
For the clojure folks there's <a href="https://github.com/fulcrologic/statecharts" rel="nofollow">https://github.com/fulcrologic/statecharts</a> which a pretty sophisticated implementation that removes the XML requirement (particularly for executable content), yet remaining close to SCXML. XState even gets a reference in the prior art section.
And for those of us who want to avoid/are allergic to XML (& SCXML -_-), there is clj-statecharts too (<a href="https://lucywang000.github.io/clj-statecharts/docs/get-started/" rel="nofollow">https://lucywang000.github.io/clj-statecharts/docs/get-start...</a>), I've always found it slightly more ergonomic and their codebase is a bit more intuitive and simpler than Fulcro's
I had used (and would gladly still use) XState, without even knowing about what "statecharts" even means.<p>I used it with lit.js to help with a drawer-like navigation component that reacts to page width and has many props and internal states. I can't even think how horrible it'd have been without XState. Thank you very much!
Xstate has helped me clean up some hairy situations in the past. Looking forward to the next version, and thanks for your great work!
XState is awesome, made a complex decentralized key sharing scheme a breeze.
With all respect to xstate, if you don't need complex nested state machines, you should check out robot3.js. The automatic TS type inference makes it pretty handy for the spots where you want a bit of state machine logic.
XState is an awesome library! Stoked to hear there's a new major version and visualizer coming. :)
Since you’re in the know, do you have any opinion on Petri Nets?
I’m not the GP, but I think petri nets are awesome. At least they’re a great way to represent and visualize many systems. Statecharts I find tricky by comparison. For a simple example, imagine you’re making a game and the player has to talk to three people in any order before moving to the next stage. this is very easy to represent as a petri net. (you just need three places and have a token in each one represent having talked to the necessary person.) But I think it corresponds to 8 separate states in an FSM (or statechart? not sure). Which just seems overly complex for a simple situation like this
> But I think it corresponds to 8 separate states in an FSM (or statechart? not sure)<p>In a conventional FSM yes but not a statechart. Statecharts support parallel regions within a single state. You’d have 3 regions for your example: one waiting for each person. There would be 4 states total: one to wait on each person, each in its own region, plus the superstate. The superstate would exit when all 3 “waiting for person <x>” sub states exited, independent of their sequence.<p>I’m with you on Petri nets though, very helpful for modelling concurrent behaviour.
When working on a project <a href="https://github.com/xlnfinance/xln" rel="nofollow">https://github.com/xlnfinance/xln</a> (a financial account network between entities) I stumbled upon a problem that you need a way to emulate a real network deterministically. Then i realized every blockchain is just replicated state machine so why dont we encapsulate every user node into Runtime->Entity->Account hierarchy of 3 state machines. Each outer machine fully controls the inner one. Like "blockchain inside blockchain" with different consensus modes.<p>Then I googled for "hierarchical state machines" and found statecharts. These two ideas are somewhat similar so here are my 2cents. Imo more software should use hierarchies of state machines to fight the worst class of bugs with non-determinism.
2 hours and not a single comment yet?! At one point, Statecharts seemed to be getting traction in the frontend/UI ecosystem, albeit tiny traction. Leveraging state machines (and particular Statecharts, which is basically compositions of state machines) for UI interactions makes complex flows so much easier to reason about! However, seems the traction eventually disappeared for unknown reasons, sadly.<p>If this is the first time you're hearing about Statecharts, I highly recommend the book "Constructing the user interface with statecharts" by Ian Horrucks (<a href="https://archive.org/details/isbn_9780201342789/mode/2up" rel="nofollow">https://archive.org/details/isbn_9780201342789/mode/2up</a>) which yes, is from 1999, but probably the best introduction for how to actually apply and use Statecharts.
Statecharts are still getting some traction! XState has over 4 million weekly npm downloads. Animation tools like Rive & LottieFiles heavily advertise state machine capabilities. AI tools like LangGraph are built on state machine foundations.<p>It'll take some time for those apps/tools to realize the full potential of statecharts, but it's a good start.
> Statecharts seemed to be getting traction in the frontend/UI ecosystem<p>Yes, I stumbled upon statecharts checking out this Godot plugin: <a href="https://github.com/derkork/godot-statecharts" rel="nofollow">https://github.com/derkork/godot-statecharts</a>
One thing usually skipped in primers: history pseudo-states (H, H<i>) make a statechart formally non-deterministic from outside. The pitch is "current state is a pure function of inputs" — history breaks that. Entering a parent via `H` puts you in whichever child was active last, so the same event from the same outer state can land you in two different inner states. That latent "last-active child" IS state, just state nobody draws on the diagram. Harel's original paper acknowledges it; SCXML and XState both implement it; nobody really talks about it. So if you're using deep history (H</i>) to preserve subtree state across re-entry, you've moved the bookkeeping into the chart engine — fine, but the picture alone no longer tells the full story, and history transitions need their own tests like any other piece of state.
hm<p>"inputs" can refer to just current and future inputs --- or it refers to the totality of inputs, including the inputs leading up to "here".<p>in the latter interpretation the machine is perfectly deterministic. and the "deep history" pointer simply is part of the state machine.
Going solely off your description of the scenario; couldn’t you trivially model any history (H,H) node as two nodes —> (A, H’) —-> (H’, H) —> (H, B), and have it be deterministic again<p>I’m essentially thinking of H’ as a write-ahead-log prefixing any node
I wonder if it's possible to combine statecharts with durable execution engines like Temporal, DBOS, Restate, etc. At work we use Cloudflare Workflows for managing onboarding and payment workflows. It generates flowchart diagram that is useful for quickly reasoning about what the workflow does, which I guess is what statecharts is trying to achieve.
I’m building Zindex [1], which is aimed at this exact “visual representation of executable workflows” layer.<p>What I'm solving for is AI-generated diagrams are usually one-shot: Mermaid/SVG/PNG gets emitted, but there’s no durable diagram state to update, validate, diff, or reuse.<p>Zindex makes the diagram itself structured state. Agents use a Diagram Scene Protocol (DSP) to patch nodes, edges, groups, relationships, constraints, and revisions; Zindex handles validation, layout, rendering, versioning, and storage.<p>So for Temporal/DBOS/Restate/Cloudflare Workflows, I’d imagine Zindex sitting beside the durable execution engine: the engine remains the source of truth for execution, while Zindex maintains the persistent, inspectable visual model derived from code or execution history.<p>[1] <a href="https://zindex.ai/" rel="nofollow">https://zindex.ai/</a>
Yeah its bothered me that workflows get all the limelight while state machines are more than capable. They just need durable execution for state charts. I think Cloudflare was going down the durable object actor model for a bit, but not sure if they abandoned that coded project.
When you say "it generates flowchart diagrams…" what exactly is generating them? Is it built into cloudflare workers or is it something your team created?
It's displayed Cloudflare Workflows dashboard: <a href="https://developers.cloudflare.com/workflows/build/visualizer/" rel="nofollow">https://developers.cloudflare.com/workflows/build/visualizer...</a>
Cloudflare workers shows a visualisation of your workflow in their dashboard, but it’s imperfect
We have been using statecharts at our company for all business processes after I wrote an interpreter for them inside Postgres.<p>It has been a great experience so darn it makes processes very resilient against change and very easy to come back to after years.<p>The library is open source too:<p><a href="https://github.com/kronor-io/statecharts" rel="nofollow">https://github.com/kronor-io/statecharts</a>
I've always been a fan of state machines and have hoped for their adoption to grow.<p>Having visual understanding of state is becoming increasingly important for AI generated code you don't nearly understand as well as the human variety.<p>It seems many still favor store based reactivity state in frontend frameworks.<p>I contribute to it being the default so why change and because libraries like xstate are far more difficult to learn the syntax and are more verbose. But with AI that's hardly an issue, so I wonder if there is more to it I don't see and we just haven't seen the state chart reach it's peak yet.
The next version of XState will be much more ergonomic, with a reduced API surface area, lower learning curve, and much easier for devs (and agents) to author.<p>But at the same time, frontier models are <i>very</i> good at writing XState.
I am looking forward to seeing it!<p>It feels bad because I know your team was working so hard pre AI to make state machines more accessible and bring such a powerful concept to the world.<p>I know it didn't pan out exactly, but I really want durable execution state machines that exceed workflows one day.<p>I keep thinking to myself can I enforce my AI layer to have some deterministic durable state machine running it and I'm not deep enough on them from a creator/author perspective to answer that question like you, but keep us posted on the changes.
Well, this is used in the automotive domain for long time now. Look at matlab/simulink: you can draw your algorithm as a state machine and generate the code out of it. Recently I implemented a state machine to manage a quite complex react component, who moves from one visual state to another through some css transitions. It’s not a difficult state machine, but I think people are not so well versed in it.
The title contains hierarchical, which does not come back in the post. You probably need hierarchy, otherwise state charts become unweildingly large.
A statechart without hierarchy is just a state machine. It's the composition and hierarchy that turns a state machine into a statechart.
It does if you click on "What is a statechart?", <a href="https://statecharts.dev/what-is-a-statechart.html" rel="nofollow">https://statecharts.dev/what-is-a-statechart.html</a> .<p>> The primary feature of statecharts is that states can be organized in a hierarchy: A statechart is a state machine where each state in the state machine may define its own subordinate state machines, called substates. Those states can again define substates.
Let me just throw in:<p>ETL State Chart and Hierarchial FSM <a href="https://www.etlcpp.com/state_chart.html" rel="nofollow">https://www.etlcpp.com/state_chart.html</a> and <a href="https://www.etlcpp.com/hfsm.html" rel="nofollow">https://www.etlcpp.com/hfsm.html</a><p>Quantum Leaps <a href="https://www.state-machine.com" rel="nofollow">https://www.state-machine.com</a><p>I've used them primarily in safety-critical systems where complexity, timing and the ability to effectively verify behaviour is obviously important. Being able to separate the decision-making from the actions is a great aid. Having to strip back the decision making to "what do I do next" when I'm in this state and this event occurs is a bit different to how most programs are structured, but really does aid separation and makes it easy to reason about behaviour under different conditions.
A long time ago, I wrote a compiler from a curly-brace encoding of Statecharts, to Java.<p>More recently, I avoided some early SwiftUI bugs by modeling some of the iOS app interaction using Statecharts, in an ASCII art comment in the code, and implementing that.
One of my favorite data structures<p>Created StateKit for ObjC/Swift some time ago, it’s been production tested in some very large apps: <a href="https://github.com/sghiassy/StateKit" rel="nofollow">https://github.com/sghiassy/StateKit</a><p>Such a cool data structure
Statecharts are too complex IMHO. I prefer to compose simple state machines to model a complex behavior instead of building one giant statechart.
I've tried to use state charts for frontend development a couple of times, but bounced off. IIRC, I was using xstate with vue, and I found that they were hard to retrofit to existing systems, and where I tried, I found that the boundary between the part of the system controlled by xstate and the rest of the system problematic. It felt like it would work better with everything "inside" the statechart, but that's a big lift for an existing codebase.
Statecharts are one of the those concepts that are extremely useful for machine control that it seems crazy to me that they are so little adopted from what I have seen. At most people might know about a flat mealy state machine.<p>What's better than graphically designing your HSM, simulating it vs all kinds of scenarios to verify it, and auto generating the code?
Since the state chart itself doesn’t contain any data, I’m wondering where the data lives and how you handle data that’s only valid in certain states? It seems like having the states separated would be rather awkward versus, say, a TypeScript union type that keeps them together?
My work in PCIe IP has regularly had me involved with reading state machine (or state chart) diagrams, the PCIE link training FSM itself have multiple sub state machines e.g. for recovery, or configuration, or power savings and it was not unusual to find a physical printed copy of this diagram in the lab to help aid in debugging.
Anyone remember Sproutcore JS? They used state charts.<p><a href="https://guides.sproutcore.com/getting_started_2.html" rel="nofollow">https://guides.sproutcore.com/getting_started_2.html</a>
Oh right, I keep forgetting about those useful-but-historically-mentally-draining-to-update sources of truth. This might be extremely useful when paired with an agent.
I’m going to give this URL to Claude, ask it to propose uses of state charts in my codebase. Yes, it already has this in its training data, but I find giving it a URL brings it to top of mind.
I had a state machine bug in my backend I built a where order states were defined differently in migration vs api routes. Wish I knew about this earlier.
Hierarchical state charts have been formalized as a type of UML diagram. Details:<p><a href="https://en.wikipedia.org/wiki/UML_state_machine" rel="nofollow">https://en.wikipedia.org/wiki/UML_state_machine</a>
I love statecharts, but I wanted to challenge some of the "why"s in this post.<p>> It’s easier to understand a statechart than many other forms of code.<p>There's a lot of arguable quantifiers here, but when I was started at <a href="https://gadget.dev" rel="nofollow">https://gadget.dev</a> (no longer working there), we started with hierarchical statecharts as a way for users to specify their behaviour (with the ability to customize transitions with code snippets). No matter what we did, users just found it incredibly confusing. This was with a customer based that had decent spread across the "how technical are you" spectrum.<p>Did we do a poor job of introducing it to the user? Maybe. We were forced to switch everything over to flat code though.<p>> As complexity grows, statecharts scale well.<p>I think there's a big asterisk on this one, likely. I had to undo a lot of unfortunate statechart code that was introduced for some of the backend of gadget, and I consider myself a pretty good programmer. Perhaps it's just the difference in paradigm, or the accidental complexity of how we worked with xstate, but I reduced 1000+ lines of very hard to read and extend statechart code to a few hundred lines of imperative code, with some hardcoded states. It was actually easier and faster for me to do this than fix bugs that existed somewhere in there (I tried, and failed).<p>Every engineer at the company (it's a small company :P) agreed that it was substantially easier to read and understand.<p>I think this perhaps echoes things said elsewhere here, like dflock's comment on the boundary between "xstate" and "not xstate".<p>All that being said, I'll restate: I love the idea of statecharts, I just have scars from dealing with them. I think they were perhaps applied in situations where the benefit was low, and the overhead of understanding the bits and bobs of xstate was too high of a cost for any perceivable benefit it may have offered.<p>> It’s worth noting that you’re already coding state machines, except that they’re hidden in the code.<p>I will say that this is a great point that may often be overlooked.<p>When I interview candidates, one problem I enjoy doing (and they do too!) is "let's try building vim" problem. We build out a few basic commands — move left, move right, replace character under cursor — to edit a string of text. The candidates that do the best often see how parsing can be encoded in a state machine and plan with that in mind. They perhaps still just encode it as if/else statements with a state variable, but that still gives the better outcome. Something like this:<p><pre><code> 0-9
---------
| |
| v hj
|-- (number N) -----> move N spaces
|
| r
------> (read char c) ---> replace N characters with c
</code></pre>
[EDIT]
And I should say, I _am_ repeating some of what's stated in the linked site (under "Why should you not use statecharts?")
I'd like to see a computer language where statecharts are primary control flow construct and ECS are primary data structure.
Protip. Claude can generate state machine diagrams via mermaidjs blocks in markdown.<p>These render in GitHub flavoured markdown
I have used nested state machines for a while now and they are really good if you have realtime needs, e.g. controlling motors, animations, audio/video playbsck and so on.<p>The statemachine itself also forces you to think about which transitions between which states are possible and whst you may need to consider when such a state change happens.
This could have been represented in a yo-dawg meme.<p>i gave it some time, but that's not a good site. it takes forever to explain simple things and never gets to any important and novel idea. i gave up when it turned out that it's just a tree of state machines - for some reason called a 'chart' despite not apparently having any chart-like property.<p>ugh. it's just a doodling exercise for architecture astronauts. OMG it actually, unironically references UML and has Statechart XML!<p>flipping the bit on this one
Is there any research in composing state machines?
While we are discussing state charts and source code generators, Qt deserves a honorable mention with it's Qt State Machine framework<p><a href="https://doc.qt.io/qt-6/qtstatemachine-overview.html" rel="nofollow">https://doc.qt.io/qt-6/qtstatemachine-overview.html</a><p>Qt also supports W3's State Chart XML (SCXML)<p><a href="https://doc.qt.io/qt-6/qtscxml-overview.html" rel="nofollow">https://doc.qt.io/qt-6/qtscxml-overview.html</a><p><a href="https://www.w3.org/TR/scxml/" rel="nofollow">https://www.w3.org/TR/scxml/</a>
"No statechart will survive contact with real world applications".
I mean, when you have external dependencies, multilayer protocols, multithreading, perf requirements, the state will becomes an ugly mess. One can only dream of a clean statechart.
Hierarchical state machines are common in hardware development. I've also used them for embedded systems, and dug my way out of spaghetti nightmares in distributed systems by reworking a system into a set of state machines.<p>Is it clean? Not always, it gets messy. On the other hand it is deterministic and traceable to specifications. Specifications as state machines can be easier understood and shared than raw code or raw prose.<p>I also think more effort is needed to synthesize a clean set of state machines with hierarchy for a system at scale and I'm sure there are times when that effort is not warranted.
I’ve used state charts in multi-billion legacy apps and they’ve stayed quite clean.<p>Just don’t use one state chart for everything. Just like any data structure, use multiple of them scoped appropriately
Sometimes the complexity is unavoidable and you have to pick the lesser of many evils. Oftentimes complexity management is trying to model the system in such a way that the complexity moves to the area which is most easily understood. It doesn't make the system less complex, only easier to reason about and maintain. State-oriented design is just a (very powerful) tool in the toolbox.<p>Even when I haven't actually used a state machine, I've modelled problems as state machines just to help me think about the system. Thinking in terms of state can often help traditional software designs.
I agree, we try to think in terms in state machine. Just complaining that somehow this is not good enough, in practice we need to add random flags, and it is not clear how to separate the multitude of separate state machines all active at the same time.
[dead]