Learn about state modeling with state machines and statecharts can improve the way you develop application logic, and get a sneak peek of never-before-seen upcoming visual tools that will take state management to the next level.
The Visual Future of State Management
AI Generated Video Summary
1. Introduction to Visual Future of State Management
Hello, my name is David Korshid. I want to talk to you today about the visual future of state management. Visuals serve as an exact specification of something that would be hard to describe with just text. The way we typically code application logic doesn't lend itself well to a visual formalism. Enter the reducer, which provides a way to contain all of this logic in a centralized convenient location. Dispatching events is a really good thing.
Hello, my name is David Korshid. I'm David K. Piano, pretty much everywhere online. And I want to talk to you today about the visual future of state management.
Now, what do we mean by visual? So you probably know what a Venn diagram is. It's a visual in an exact way of representing commonalities between two or more different things. And you might have also heard about a sequence diagram. And so this describes how different parts of a system communicate with each other. Now, diagrams like these are very useful for conveying relationships in a visually unambiguous way, each with their own special notations that mean specific things. And state machines and state charts, which I talk about a lot, those fall under the same visually exact diagram category in that they describe the logic and the behavior of some special entity using some special notation like arrows and boxes and regions.
Now, David Harold, the inventor of state charts, calls this a visual formalism. He describes that visual formalisms are diagrammatic and intuitive, yet mathematically rigorous and precise languages. So thus, despite their clear visual appearance, they come complete with a syntax that allows you to determine what's allowed and what's not allowed. And it also comes with semantics that determine what the allowed things actually mean. So these kinds of visuals serve a higher purpose than to just make your boring documentation look a little bit nicer. They serve as an exact specification of something that would be hard to describe with just text.
So the way that we typically code application logic doesn't really lend itself well to a visual formalism or to anything really. We tend to co-locate data and logic close to the source where it's used, such as directly in event handlers or in promises or in callbacks or things like that. Now while this may be convenience to code, the problem is that this logic is hard to understand, especially as it changes over time due to events or anything else that can happen. And you can't really discern what can happen exactly or how an application can respond to an event at any point in time. That connection logic, it resides mostly in the head of the developer who coded that logic, which isn't really useful. And worse with ad hoc logic, that tends to get repeated throughout the code base. So even if you attempt to drive this up, you have that same ad hoc logic living somewhere else instead of a centralized place where all of your logic lives.
So enter the reducer. Of course the reducer was popularized very early on by blocks and state management libraries like Redux. And reducers are what were used to provide a way to contain all of this logic in a centralized convenient location. So one important and hugely beneficial constraints of reducer is that it enforces you to interact with the logic via sending events or actions as they call it in React and Redux land. By the way, the naming of actions, I don't particularly like, I think it was a mistake. We're gonna be using the term events in place of actions throughout this presentation. But here's why dispatching events is a really good thing.
2. Introduction to State Machines and State Charts
It forces you to reify what can happen in your app at any point in time. Reducers typically contain switch statements or if statements to discern what should happen when an event is received. State machines cleanly separate behaviors into finite states, preventing impossible states and transitions. State charts take the visual formalism of state machines further by introducing hierarchy and allowing for a clearer representation of complex logic. XState was created to provide a mathematically rigorous visual formalism for state charts.
It forces you to reify what can happen in your app at any point in time. So the user may click a button, a fetch may resolve or reject, a timer might go off. All of those are events. And thinking about your app in terms of events really simplifies the mental model. However, this isn't easily visualized either. Reducers typically contain switch statements or if statements to discern what should happen when an event is received. So that's distinguishing how the behavior of your app can change becomes a lot more difficult. It's mixed into those switch statements and you have to piece together all of that logic and navigate through a bunch of defensive statements like ternaries and if statements just to make sense of the logic.
So it's as if your reducer is a single statement in a state machine with the single state in a bunch of conditional and sometimes unnecessary transitions. It might work and it might do the job that it's supposed to do, but it's difficult to understand and it's still prone to impossible states and transitions. So state machines, by the way, they're like reducers and I talk about this pretty much everywhere online and state machines can also be written as reducers, but instead of mixing all the logic together, it cleanly separates behaviors into what are known as finite states. A finite state represents a behavior. What is the current states of an actor and how it could respond to events. So it might respond to an events by doing an action or by changing its behavior, which is represented by the transition arrows that you see here going from states to states. Or in events might not be handled. In which case the default behavior is to ignore the events. In reducers, this often requires a lot of defensive code like if statements. In state machines, it's built right into the mathematical model. And more practically, this kind of mechanism prevents impossible states, which guarantees that two behaviors can't occur at the same time. And it also prevents impossible transitions since all transitions between finite states must be explicitly written. And like you could tell over here, it lends itself well to visualization. We can understand how some actor can change its behavior by playing the events on the diagram, following the arrows and seeing what the next finite states should be.
Now, state charts take this same idea of a visual formalism introduced by state machines and it takes it one step further. It introduces hierarchy among many other things. So although state machines provide a way to cleanly organize logic, they suffer from combinatorial explosion of states and transitions, especially when different finite states are actually related. By extending the notion of state machines to be a hierarchical graph or a high graph as David Harrell calls it, we can group states together to represent common transitions cleanly. We can also isolate logic so that we see the bigger picture instead of having to understand all the little implementation details at once in a big flat structure. Like state machines, state charts are also mathematically rigorous visual formalisms. They can express a much higher degree of complexity than state machines and they can represent it in a clear and visual way. So that's why I created XState a few years ago.
3. Introduction to XState and its Features
4. XState: Model, Tags, Wildcards, and More
This allows you to define a model for both context and events, making it easier to use in your machines. Tags provide an easy way to reuse state machines in different contexts. XState v5 introduces partial wildcards for specifying events and higher level guards for conditional transitions. It simplifies the actor model, fixes bugs, improves TypeScript typing, and makes the library more modular and smaller. XState is not just a state management library.
And so this allows you to define a model for both context and events and in the future actions and things like that, that make it a lot easier to use in your machines or in multiple machines. And so this is provides an easier way and a more type-safe way to work with a specific data model with your state machines.
Another recent change is tags. And so with tags, we could give some finite states and tags, which you could think of as class names in HTML and CSS and we could say all of these dates have a... So, we could basically, this should be loading not pending, but we could basically say that when we are in one of the finite states that has this tag, do something like show a loading spinner or something like that. And this makes it really easy to reuse state machines in a variety of different contexts.
Now in X state version five, there's a lot of new things coming too. And we're working really hard to get this beta released. One of the cool things is partial wildcards. So now you could specify events that, like for example, mouse.star would represent in events like mouse.click, mouse.move.out and further. So you could specify partial events and capture transitions for those events. You could also specify higher level guards. And so, just a refresher, guards are what cause transitions to be taken or not to be taken. So they're basically a conditional transition. And so now with higher level guards, we have a way to combine difference predicates together in a single transition. And this lends itself really well to visualization too. So in the future, you're going to see these guards basically visualized as a decision tree, which is pretty cool.
So there's a lot of other things coming to X-State v5. First of all, we're simplifying the whole actor model behind it, where everything is an actor instead of special casing, promises, observables, callbacks, things like that. We're just having one unified interface that if it's an actor, if it's something that you could send events to and receive events from, then X-State is going to work naturally with it. And this opens up a whole lot of possibilities in the future with integration with other frameworks and other libraries too. Also in order assign, this was a bug which is technically breaking in v4, but that's going to be fixed in v5 so that when you make assign calls, they happen in the order that they were specified instead of at the very beginning. We're also working really hard on the TypeScript typing in order to strongly type actions, services, guards and more and also state keys and things like that. So basically making this as good of a typing experience as possible for the developer. Speaking of developer experience, we're also working on making it modular and smaller so that you only need to import the things that you care about. It's been often said that XState is very feature rich and you might not need all of those features. And so if you wanna keep the bundle size down, you could import just the things you need from XState instead of everything. And of course, this is just a short list of many more improvements that are coming to version five. And we're always open to your suggestions on what you want us to make better with XState. But yeah, this is all to say that XState is not just a state management library.
5. XState: Future Goals and Stately
XState has many goals beyond state management, including visualization, testing, analytics, and auto-generation. XState Inspect allows real-time visualization of state machines. The recently announced xstatecatalog.com provides useful examples of state machines. XState aims to address the challenges of understanding code through documentation, diagrams, and executable diagrams. The future visual software modeling suite, Stately, will enable collaboration and understanding of application logic across all levels of the stack. Visit stately.ai to subscribe to the mailing list.
It has many goals that go far beyond just the purpose of state management. For one, visualization. We want to make it so that anything that you create in XState can be automatically visualized in real time, and I'm gonna show you that in the coming slide. Also testing. We have XState Test, and we also want to make it capable to automatically generate tests and use that with your end-to-end testing suites, and just make it a much better testing experience so that you don't have to manually write all of your tests. Also analytics. XState, since it's not just a black box, it's a directed graph where you could know all of the state transitions that can happen. We can record analytics and see exactly what happens in your app as a user goes through it. Of course, this would be an opt-in tool, but it's something that we're working on, and also auto-generation. Again, because we have that state machine and state chart described as a directed graph, we could do some really, really fun things like auto-generating tests and documentation and diagrams and even other formats.
Now, XState Inspect is one example of this. I released this a few months ago, but XState Inspect is a utility that allows you to visualize state machines in any framework in real-time. And in this example, it's a timer that we're interacting with, and you could see the state machine in the bottom changing as we click around. And this works both ways. So if you click in here or send any events through the inspector, it will also affect the application. And so that's a small peek into the future of where we see XState's tooling. This has also been used in the recently announced xstatecatalog.com by Matt Pocock, which is an awesome catalog of many useful examples of state machines that you could copy and paste directly into your app. And you can even interact with the documentation here and see the visual diagram on the left change, which is really cool. So I encourage you to check out xstatecatalog.com.
But overall, the current state of things, and one of the biggest reasons I created XState was because it's hard to understand how your code works. And if it's, you know, the more features and the more code we add, the more bugs and the more edge cases were unintentionally introducing to our applications, which means, you know, we need more tests for full coverage and we need more developer effort, which costs money and time. Now, documentation helps, but it quickly goes out of date and it often fails to describe the system at a higher level. Diagrams are useful for this too, but they're tedious to create and they're also quickly outdated. And generating diagrams from code are a great solution to this, but I think we can do even better because I believe the future is executable diagrams, which are diagrams that aren't just generated from the code, but can be converted to code and also visually edited. And so this opens up the ability to collaborate with less technical people like designers and project managers, while also allowing developers to quickly understand how the logic works at all levels of the stack without worrying about outdated docs. And so that's why I'm really excited to announce Stately, which is going to be a future visual software modeling suite for creating, editing, simulating, analyzing, testing, and collaborating on application logic and workflows for any language in the future. So we're taking X States and its tooling to the next level to make your code do more. So I encourage you to visit stately.ai and subscribe to the mailing list to be the first to know when the beta is released. And with that, thank you for watching JS Nation. Thank you, David, for sharing your knowledge and expertise around state management.
Q&A: State Machine Adoption and Testing in XState
We have equal number of votes for two answers: one half of the people answered not yet, yes, I'm not using state machine, and the other half answered yes, I use it with a library. State machines have traditionally been an academic topic, but now more and more people are using them to model their application state. Testing in XState is great, with pure functions for testing state machines and the Xstate-test library for testing entire applications.
And we have a lot of questions for you from our Discord channel, but before questions for you, let's have a look what folks answered on your question. So I open Slido, and wow, that's really interesting. So we have equal number of votes for two answers and they leaving these two with a large margin. So one half of the people answered not yet, yes, I'm not using state machine, and other half of people answered yes, I use it with a library. That's really interesting.
So what do you think about these results, David? And welcome to our studio. Thank you, I think that they're surprising but not too surprising because if you were to ask this question maybe a year ago or three years ago, you would have people saying mostly no or not yet. And they would be saying that because state machines have traditionally been a very, I guess you could say an academic topic, not a topic that's really prevalent in software development, unless you've studied things like UML or embedded electronics, or just formal patterns and stuff like that. But now we're seeing that more and more people are understanding the value of using state machines and state charts to model their application state. So it's really encouraging that a lot of people are using state machines in their applications now.
Yeah, yeah, yeah, fair enough. And I think there was a trick in your question because I didn't pay maybe too much attention to the exact wording and I've seen something, oh, something about state. Yes, I use, of course I use state library, but it was not about just generic state library. It was about state machine. And yeah, personally, I didn't use it in my project myself. So maybe after your session, I will definitely give it a try. Well, let's see what our dear attendees want to ask you. Yes, let's keep the question about future for the future. We have enough time to do this. Very, very practical one. How does testing look like in X state world? Well, testing looks great. And so there's two angles to this question. First is testing the state machines in X state itself. The state machines, like I showed, they have a transition function. These are pure functions, which means that if you want to test that after a user does X number of events, it ends up in a certain state, you could just do that. You could send the events to this pure transition function of the machine and just assert that it is in the states that you expect it to be. And not only that, you could do like state.matches or with the new tag, you can do state.hasTag and just make sure that not only you get the correct states but also that the correct events are fired. And on the other side of this, there is a library, an accessory library, to Xstate called Xstate-test, and so that allows you to do much further than just testing your state machines. You can test entire applications even if they're not written with state machines at all, and it doesn't matter which framework they're in. What you do is you describe your model as a state machine, or like the model of the application, and you model it as a state machine, and you run that through Xstate-test, which is going to generate automatically all possible ways that the user could go through the application and ensure that all of the expected states are reached.
Testing, Learning Curve, and Adoption
Xstate allows easy mocking of side effects and testing of effects. The learning curve from Redux to Xstate is shallow, with support for combinatorial machines. Migrating from Redux to Xstate is easier with less code and built-in side effect management. Xstate is a natural fit for Redux, Vuex, and Ngrx users. Helping developers adopt new technology is crucial for its success.
So it's like doing end-to-end tests, but at a much bigger level. And also one thing I wanted to mention with testing. Because of the way that Xstate allows you to specify actions, guards, services, et cetera, as a secondary thing, you could very easily mock any side effects in there. So it's sort of like dependency injection built in right to Xstate. And effects are first-class citizen, so you could also test effects as well. So, yeah, testing's great in Xstate.
Yeah, yeah, fair enough. So to sum up your question, there is no excuse for us developers to ignore testing in Xstate and other state machine libraries, because the tools are there, let's just use them. And from what I understood, the developer experience is quite okay when you use this tooling.
Right. Okay, let me pick the next question. And yeah, let's pick this one. How is the learning curve to use Xstate if you have some experience with, for example, Redux? Yeah, so if you have experience in Redux, then the learning curve to Xstate is actually very, very shallow. In fact, with one of the most recent updates, we have added support for what are called combinatorial machines. I don't like the name. It's just a name that was the official name of it from Wikipedia. But what it means is a state machine that only has one state. And so making a reducer into a state machine now becomes as easy as instead of putting everything in the big switch statements, you put it in an object. So you're basically converting switch to object, which means you write a lot less code and you can do things like manage side effects right in there as well. So you can even refactor things from Redux. But this makes the migration to Xstate a lot easier. So yeah, and the same thing with Redux, if you're using anything like Redux, Vuex, Ngrx with that advanced based architecture, then Xstate is going to be a very natural fit because everything depends on events for the communication mechanism. So yeah, I recommend if you know those libraries, then don't fear Xstate because the learning curve is not that bad. You're pretty much almost already at the top of that learning curve.
Wow, that's cool. Sounds really promising. I really think that helping folks to adopt a new technology is a key to success of this technology. So that's really cool. Let's take the next question and yeah, let's go for this one with many details. So the question is our applications is around 100,000 lines of code of NGRX complex logic and such auto-generated graph would be a holy grail.
Using Xstate with NGRX for Visualization
In theory, it is possible to use Xstate in combination with NGRX for visualization. The machine.transition function can be used with any existing state management library. The goal is to make migrating to Xstate as easy as possible.
Do you think using Xstate in some extent with combination with NGRX just for the visualization is a good idea or do you have some advice how to compose Xstate or Stately with NGRX for the visualization? Yeah, so the question of like, you know moving from NGRX to Xstate and like using it for visualization that is a very interesting question because in theory it can be done cause with Xstate you can use the machine.transition function with virtually any state management library that you already have. And that's something that we're gonna be focusing a lot in the future too, which is just working with NGRX, UX, Redux, all of these existing management libraries. But in theory, yes, it is possible to just use that transition function, put it in NGRX and be able to visualize your application logic right through there. And so long story short we're still experimenting with that. We know that migrating a hundred thousand lines of code to X state is a non-trivial task. So our goal is to make that as easy as possible. Awesome. Awesome. Yes. Great plans.
Using X State between Frameworks
X state allows you to use the same machine in any framework or even no framework at all. It's a natural point of unity for developers using different frameworks like Angular, React, Svelte, or Vue.
So that's interesting. We went through a Redux which is I believe more React-ish thing. We went through NGRX which is Angular thing. And we couldn't find better shortcuts to the next question, which is, can you use X state between frameworks and keep functionality? Yes, you absolutely can. And in fact, this is one of my favorite features of using X state and state charts. I have a demo, I'll try to find the links and put it on spatial.chat afterwards. But I recreated the, there is a timer on the Android phone and actually it looks like this. I could show you like you would have a little stopwatch and play it. So this, I recreated it in REACTS using X states and the state machine for that timer. And I wanted to see how fast can I migrate that or not migrate, but use that logic and recreate that timer in view. And it took me all of 10 minutes. And most of those 10 minutes were just finding how to use Font Awesome icons on the view application just because I'm not that good at view. But yeah, I use the exact same machine. So it's extremely flexible. You can use the same machine in any framework or even no framework at all. That's really cool. And this is like very natural point of unity of folks who develop using different frameworks. Yes, either your Angular or REACT or Svelte or Vue. X state is like a point of connection in these dev teams.
Q&A: T-shirt and Future of X State
Before we move on to the next question, let me address the fan's query about my T-shirt. The T-shirt is from the key framers, a weekly live stream where we bring imaginative user interfaces to life. You can get it at keyframe.rs. Now, let's talk about the future of X state. We're working hard on version five, updating the visualizer, and planning to create a drag and drop editor and a registry for collaborative machine creation. Visit stately.ai to stay updated. Thank you for having me!
Now we have two minutes left and the question is the one I wanted to take from the very beginning. What is the future of X state? So the future, you know, since I left my job at Microsoft, now I'm working on X state and related tools full-time. So we're working really hard on version five. We are working on also like updating the visualizer, which is coming soon. And I'm super excited about that because the current visualizer is running on an old version of X state. And so we really want to refresh it and make it so that you can visualize multiple machines and you have VS Codes Monaco editor in there as well. And so in the future, we want to create a drag and drop editor, a registry for anyone to be able to share and work and collaborate on machines that they create visually and use them directly in their projects. So there's, there's a lot of things that we have coming planned. And if you go to stately.ai and sign up for the newsletter, you're going to be the first to hear about it. Thank you very much, David, for sharing your session, for sharing your answers and sharing the future of state management. See you soon. Bye. Thank you for having me.