# Reactive State Machines and Statecharts

Canonical: https://davidk.dev/talks/reactive-state-machines-and-statecharts/
Video: https://www.youtube.com/watch?v=GSHQFx7PG20
Speaker: David Khourshid (@DavidKPiano), creator of XState
Type: Conference talk · Event: Uphill Conf 2019 · Year: 2019 · Duration: 21:25 · Views: 2929 (as of 2026-10-19)
Topics: Statecharts, State machines, Reactive programming, Visual modeling, Event-driven architecture

## Summary
What if you could automatically visualize your application logic? Discover how state machines and statecharts can help increase the speed of development, eliminate entire classes of bugs, identify all possible edge cases, generate integration tests, provide comprehensive analytics, and more. These decades-old software modeling techniques have been proven in other industries and mission-critical so

## Key takeaways (quoted from the transcript)
- I also work in Microsoft and I'm really excited to be here at Apple Comm talking about reactive state machines and statecharts. (0:00)
- A mapping of state transitions which are triggered by these events, which transition from one state to the next state, and then final states. (7:00)
- I think the visualization part is probably one of the best parts of having finite state machines and statecharts in your application. (14:00)
- Where you could take these state machines to generate tests, that's right, you don't have to write the tests, you take that state machine and statechart, and you generate tests based on that. (18:00)

## Chapters
- 0:00 Introduction
- 3:00 You have a state and event and then you get the…
- 10:00 I've been working on this library called XState…
- 16:00 Where you could take these state machines to generate tests…

## Transcript
[0:00] So, yeah, just like Sean, my name is David. I also work in Microsoft and I'm really excited to be here at Apple Comm talking about reactive state machines and statecharts. Also, if you couldn't tell I lost my voice a couple days ago, you know, wasn't feeling too well, so please bear with me. Okay, sorry, sorry, okay, anyway. So I want to talk about a little story that some of you might be familiar with.

[0:00] I work at Microsoft, so I don't want to say the name of this company, so I'm just gonna use emojis. A Apple FaceTime bug? If any of you recognize this series of events. If you don't, I'll remind you. Basically, when you were making a FaceTime call with someone on your Apple phone before they even answered. What you could do is you could swipe up at a add a new person to the conversation, and you could add yourself as that new person.

[1:00] And what that did was it activated the microphone of the other person so you could listen to them before they even picked up the phone. Which ya, I'm not even kidding. This happened and it was reported, and so Apple just scurried to find a really quick way to fix it. But we have to ask ourselves, how could these types of problems be avoided? I mean, sure, Apple might have a really good development team, a really good QA team, but bugs like this are very easy to sneak past in production.

[1:00] And the core issue, like, I don't know exactly what happened, but the core issues is that something happened in the states that it wasn't supposed to happen in. So let's see how this manifests itself in the applications that we have every day. Let's say you have a button such as a search button or a fetch data button where you click it. And eventually you get a response, right? This might be the minimum viable thing that you might want to do in a web app.

[2:00] And it works in. You know, it works fine, but let's say that this request takes a long time, right? Then you might want to add something like a loader and tell the user, Hey, this, this request is taking a while. And then, of course, you get 200, okay, but if you're like? Me, you get really impatient, so you start clicking that button many, many times. And so what results is many API requests?

[2:00] How many of you have run into this problem? Where it's like, alright, now we're making way too many API requests, so you have to find a way to mitigate that. One way to do it is to disable the button, and sure, that works, I guess, but again, if you're like me, you could go in the Dev tools on disable it and then click it a few times, right?

[3:00] So that's why I say that the most neglected variable in programming is time. Because we don't think about what could happen when it does happen, and we can't predict the future. And we can't talk about, like, or figure out every single possible events that could happen in the course of a user using the application. And so that's why when we talk about state management libraries, they're they're all about like, you know, if we have a state and events, then we have the next state.

[3:00] So obviously, basing what the next state in our application is on an event, that's not exactly the right way to go about managing states. And so you have things like Redux or NG RX, or NG access, or well, whatever other things you all have. And so you have a state and event and then you get the next state. And, as some of you using NG RX may know, you have manage side effects.

[4:00] So this doesn't tell the full picture either. But really, what we need to do is have the state and the event represent what the next states going to be, as well as a declarative representation of what our side effects are going to be. So there's many different ways that we could represent these, these events and changes in state over time. And this is part of the problem. To where we have, you know, callbacks, we have promises, we have async await, and we have my favorite observables.

[4:00] And and they talk about just different ways that we handle events and in changes in state over time. So the weight that we normally program is called the bottom-up approach, and so we see this, even with reactive programming. Right where you know, we would have, like, a from event or. From events pattern and a clique or something, but then either in our observables are, in the end, beam method handler itself. We would have all this different logic, you know, just stuffed inside this event anywhere, and that's not.

[5:00] That's not really good, because then all of your logic becomes spread out, you know, throughout the entire program. So we call this bottom-up code because we're not coding from a top-down perspective of let's plan out everything, instead we're coding from me. Let's let's just start putting things in event handlers in seeing where that takes us. And there's a few problems with that. First of all, it's very difficult to test because your logic lives in so many different places in the application.

[5:00] Which also makes it very difficult to understand if anyone were to ask you like, what features are part of the app or how the app works, you have to go through so many different files to understand it. So this means that it's very likely that your code will contain bugs. Just because it's very hard to figure out where all of the logic in your app lives. This makes it very difficult to enhance and add features to your app, because when you do, you increase the complexity of your app, and, in fact, features make it worse.

[6:00] So how could we instead take a step back and look from a top-down approach and model the behavior of user interfaces instead? So this is where we get into finite state machines and statecharts. How many of you are familiar with these? All right, that's awesome, so about half of you, that's really, really good. So just a quick summary for those who don't know. A finite state machine has one initial state, which is either just it's not, I'll, it's idle in this example, but yeah, initial state.

[6:00] It has a finite number of states, a finite number of events that could either be initiated by the user or the application itself, or any outside forces. A mapping of state transitions which are triggered by these events, which transition from one state to the next state, and then final states. Which just say, Hey, we're done. And so by doing this, we could represent our apps in a very declarative, very visual way, using these state machine diagrams, and so um.

[7:00] A lot of you are fans of like, RxJS. And so you could see like, there's a lot of parallels between, you know, marble diagrams, or as I like to call them, observables. And in these diagrams over here, because it's a very visual flow of what's happening throughout your application. So, traditionally, you could use switch case statements, of course, but I like using objects instead because objects are much more terse and they're a little bit easier to read.

[7:00] And you could also, you know, take this object and you could enumerate through all the states and all the events. And so in this case, like, let's say that we're in the searching state, and let's say that the resolve event happens. Now we're in success, and so this is just a simple object. Look up, you know? So our transition function becomes just as simple as take whatever seat we're in. Figure out what the next state is based on the event, or stay on the same state if we didn't figure out what that next state is.

[8:00] So I made an example, an example of application here I took inspiration from. There's this guy called Gal Shear over on Tribble. It's like, design your week, so I just did this. I took all the weekdays out, you could drag Sunday out. It's pretty fun, but as fun as the animation looks, it's actually a lot more complex than you would think. Look, look at the mouse. When we're dragging, it's doing many different things.

[8:00] First of all, it's it has that blue, you know, the blue rectangle. But then now dragging does a different behavior, and now drag does yet another behavior. So how do we manage that complexity, you know, in this app? Well, you use the state machine so we can have different finite states, such as selecting selected, dragging. Disposed when it goes in the garbage, and then grabbing when you're actually grabbing a day and stretching it out.

[9:00] And you can have different behaviors to find for each of those states. And so this is a very visual and clear way of representing, you know, this application. And so without this I. I don't know how I would have been able to do it. But you know, this just gives me a very clear top-down overview picture of how my app. Is supposed to behave so. Also with state machine software, bugs are made visually clear, and so in this example, what's missing?

[9:00] Anyone want to shout it out? Nope, okay.

[10:00] Error, you all are too confident in your code. You're like, no, my fetch result could never fail. No, when you're loading, you could definitely fail, so you know what happens if there's an error? Well, we have a failure, but now there's something else missing. When we're in this failure state, we need some way to go back. Otherwise, the user is stuck in this failure state. And so we see this happen in apps a lot of times, where we're stuck in states.

[10:00] And the solution is just, you know, restart your phone, or restart your computer, or refresh the webpage, or something like that. So now a big question is like, these are good ideas, and these are ideas from, you know, they date back to the 1940s, even 1930s. They're extremely old ideas. And they're in fact how our entire computers work. But does it scale? And the answer is not really. But that's why we have.

[10:00] We have this thing called statecharts, and statecharts were created by a Jewish or Israeli. Not a doctor. He's a computer scientist named David Harel in 1987. So pretty old ideas. Statecharts enhance what state machines are by adding a few things. First of all, they add actions, and you could think of actions as too cleared of side-effects. So you could have an on entry, on exit, or actions between transitions. There's also guards, so you could say you could only transition from this date to the other one if the if the guard matches.

[11:00] There's also hierarchy, so you could nest state machines within each other and that way you could refine the behavior and have true separation of concerns. There's also orthogonal T, where. If you know that two different parts of the app don't interact with each other or have separate concerns, then you know you could have them separate. And then there's history and a few other things, too, where you could go back to the previous state that you are on.

[12:00] And so just an example of, like, how parallel states are useful in other concepts like this, like, let's say you had the bold italic and underlined, obviously you. Don't want to represent each of those states because you get an exponentially big number of states. So instead, we separated into just three different regions, and we could say each one of these regions can be in one of these two states. And so also having a hierarchy of states is really helpful for sharing behavior, for example, these success and failure states both shared the search outgoing transition, in which you could search again from those states.

[12:00] So instead, we could just wrap these in one state and then we could, you know, perform the searching or go to the searching state from any one of those states. So I've been working on this library called XState, which is for finite state machines and statecharts. And I've been working on it for a couple years now. And so it has all these features of state machines and statecharts. But the best part about it, in my opinion, is that, remember this object that we created in beginning.

[13:00] The API is basically the same, so you would just wrap all of this in a in a machine factory function. Sorry, and there you go. What's cool, though, is, and so, you know, I know what you're thinking. You know, we have a lot of state management libraries, and you know why add another one? But because of the declarative nature of this, and because of the fact that you're defining what's essentially a directed graph of the behavior of your application.

[13:00] You could actually and see if I could go here. You could actually take that code and you could copy paste it. I don't know if I copied it, but you could copy and paste it in a visualizer. So I'm just gonna take this, put that exact same code here and I'll zoom in for you. And then you have this visualizer which visualizes your application state so you could even go through it.

[14:00] And you could play around with each of the transitions and make sure that the behavior of your app matches what you expect it to. So I think the visualization part is probably one of the best parts of having finite state machines and statecharts in your application. So this is all made possible because we're not just using a plain reducer, we're not just using. Something like Redux or our NG RX, where it's like anything goes in that function.

[14:00] But instead, we have a very structured way of delineating our states, our events and the transitions between those states. And so, you can imagine, in RxJS, it becomes very simple to integrate. Because this machine dot transition function is itself basically a reducer, which means you could stick this right into scan there, like the scan operator, and you could. You could basically represent the finite states of your application through that steam machine as well, because a state machine is just basically a glorified, you know, reducer function.

[15:00] That not only gives you the next state, but also gives you the next actions to execute to. So, there's a lot of really cool projects that have been using AK state and state machines and statecharts in general in their application. Such as this example from Vault, where they have a contextualized like, I guess it's like a tutorial menu. As you go through the application, it, it contextually shows you like how to use each part of the app.

[15:00] And there's a whole bunch of other things too, such as reacting. I know many of you don't really use React, but reacts pretty cool, you should try it and also Gatsby service work ease if you've looked at that.

[16:00] And also in the Chrome Dev Summit, they mentioned this in pairing with the actor model, which I thought was really cool. So because XState is just in state machines in general, so don't think I'm just talking about XD. But just because it, it does have that representation of next state based on current state and events. Just like NG RX, you could reuse Redux Dev tools, and yeah, so I actually try to do this in NG RX.

[16:00] This is how far I got so far anyway. So the future of state, you know, it might be like me talking about, like, alright, what's the future of state management? And everything? But honestly, what I'm presenting to you is absolutely nothing new. There is a spec for this called SC XML, which stands for statechart XML. And I know no one likes XML except to React developers because we like to, you know, put everything in JSX, and so SE XML has interpreters in many different languages.

[17:00] And applications such as QT and you can do which you can do could generate code for Java and C++, and seemeth QT and even TypeScript as well. I believe, and so this has been around for many years now, almost half a decade. So there's many advantages to using statecharts, and one of the biggest advantages I've seen is actually from the statechart. From from the Curiosity Rover, well, some of the advantages that they talked about was visualized modeling, precise diagrams, automatic code generation, which is interesting because you would build this day chart for the other, the Curiosity Rover.

[18:00] Which, by the way, this is like a multi-billion dollar project where you have only one deployment chance. Imagine if you had a project like that, right? You don't want to screw anything up, okay, you want to make sure that absolutely everything is perfect. And so you also call comprehensive test coverage, which is something I'm going to be talking about in the future. Where you could take these state machines to generate tests, that's right, you don't have to write the tests, you take that state machine and statechart, and you generate tests based on that.

[18:00] And also accommodation of late-breaking requirements and changes, which we all have to deal with. And we all have to find a nice way to put that in our application, you know, just without having fear that something else is going to break. So there are disadvantages, though, for one the learning curve, we shift from programming to modeling. So before you even start typing any coding, you have to think about, how is this going to work?

[19:00] What are my states, what are my transitions, and how is my entire app going to be modeled? And so this modeling requires a lot of planning ahead. You, you can't just start, you know, start coding right away, and of course, not everything can be modeled yet, and so you have to have some allowances for. This part of my app is going to be modeled as a state machine or statechart, and other parts are not going to be.

[19:00] But we're gonna have some integration points where it still fits in with the state machine model. And so there's also complexity, trade-offs to finite state machines. There are simple representations of, you know, states. And events. But the more states and events you have, the more that these transitions and states just explode exponentially. Bottom-up coding, which is the coding that we're used to doing, just gets more complex over time, in a pretty linear fashion.

[19:00] But with statecharts, even though there's higher complexity upfront over time. With more states, it becomes a much more manageable way to deal with the different states and events and transitions and features in your application. So, in terms of resources, I highly recommend this one's De Chartes Tejada Oh, made by my friend Eric Mogensen. Which which talks about in practical detail about all of the different uses for statecharts, and also a lot of the terms and glossary involved.

[20:00] So if you want to get a head start on that big learning curve, this would be a this would be a really good place to start. And so basically, I just want you to make your code do more where, instead of just coding for the sake, of, you know, getting the task done. Have your code do more, have your code. Be able to one date, generate tests to visualize your application, logic and so much more.

[20:00] So, thank you so much uphill goth.
