Hello XState Part 1: Learning state machines for frontend web development
Tags: xstate, statemachines
Published: 2020-07-12 12:35:33

I’ve heard of state machines before; probably clicked a link or two; but never looked further. I had an impression of something super difficult and “computer-sciency”. I also could not imagine where and how it would fit in my day-to-day web development workflow.

Boy, I couldn’t have been more wrong.

[This talk](https://youtu.be/I1rG6UvIWi4?t=15732) by Prabu Rangki cleared my misconception and got me [hooked](https://xstate.js.org/docs/recipes/react.html#hooks) (heheh) on state machines, specifically XState.  This is the first post in–hopefully 🤞🏽–a series that documents my journey to learn XState.

So… what are these _things_, exactly?

## State Machine

A __State Machine__ (also known as __Finite State Machine__) is a pattern.

It’s a mathematical model of computation with implementations all across various science and programming fields. [Wikipedia definition](https://en.wikipedia.org/wiki/Finite-state_machine):

> A [state machine] is an abstract machine that can be in exactly one of a finite number of states at any given time. The FSM can change from one state to another in response to some external inputs; the change from one state to another is called a transition. An FSM is defined by a list of its states, its initial state, and the conditions for each transition.

A basic example of the state machine model is the _traffic light_. It has 3 states※: `red`, `green`, and `yellow`. It can only be in _one_ state at any given time, and it has specific conditions for transition between states (ie. `red` can only go to `green`).

※ _Except for one near my place, that sometimes go into an `off` state at nights and would start working again during the day._

To learn more about state machines, check out the links at the end of this post.

## XState

__XState__ is a [JavaScript state machines library](https://xstate.js.org).

There are other state machine libraries or, if you only need the most simple implementation, you can write your own.

XState, however, has additional functionalities for various use cases; and as a popular state machines library it has numerous tutorials and learning resources. For this reason I’m going to start with this library.

## State machines for frontend web development

A large portion of modern web development, especially the frontend, is about _dealing with states_ at various levels and rendering the appropriate UI.

For instance, in a page that shows a list of data (users, posts, products, etc), we render different views for at least three states: `loading`, `error`, and `success`.

- While we’re still fetching data, we show `<div>Loading…</div><img src="spinner.gif" />`.

- Then as soon as we get the response, 
  - If the response is an error, we show `<div class="text-red-600">Oh no! There’s an error.</div>`
  - OR, we render the list of data if we get a successful response.

In real-life apps, the scenario and user stories may be more complex and require more states.

Why do I want to use state machines for my application states?

### Separate logic from UI components

Presentational UI components should deal with logic as little as possible. A button component only needs to know if it’s _active_ or _disabled_. If _active_, I may style it with the brand color; otherwise I may gray it out and apply the `disabled` attribute for accessibility.

Ideally, this is not the place to do things like:

- Check whether user has at least an item in the shopping cart (if a “Checkout” button)
- Check whether user has clicked once and now the app is sending/loading the data (if a “Submit” button)

We can abstract away the conditionals and functions for these tasks to the state machines, reducing potentially buggy nested conditionals and duplicated code in UI components.

### Have a “bird's-eye view” of our application states and logic

Writing state machines help us focus on all the possible states, how the states relate to each other, and what actions can happen in each state, thus also ironing out all possible problematic/buggy scenarios, be it code issues or UX issues. It may force us to think at what level a particular _machine_ should be in relation to a view or UI component.

You may notice that these benefits so far are _not exclusive_ to state machines. Same things can be achieved with state management libraries like Redux; (if using React) APIs like HOC and Hooks; TypeScript to enforce data models and catch errors if you do something you’re not supposed to do in your current states. This next benefit is what sets XState apart from other solutions.

### Framework agnostic

XState can be used in any modern JS app, with or without frontend framework. To me, versatility is a big selling point as it enables me to abstract my code away from any specific framework, thus avoiding being “locked” into it, _and_ reuse it in multiple apps/products※※ regardless of stack.

※※ Untested hypothesis: I should be able to publish the machines code and have (eg.) a vanilla JS app an a React app import and use it, I believe?

### State Machines as documentation for stakeholders

In production apps, we work with stakeholders such as Project Manager, Product Owner, QA, and UI/UX Designer. Application states are often insufficiently documented, existing only in the codebase (API code, eg. Golang models, and frontend code, eg. Typescript definitions). We have to resort to temporary solutions like writing long descriptions in Jira and hopping on calls to ask for/clarify specifications verbally.

State machines can serve as the “single source of truth” for application states. They can be used as the basis for discussions, and once signed off on by all stakeholders, developers and designers can proceed with the implementation. Having this documentation can especially help frontend devs and UI designers on the same page regarding what design comps are needed.

XState has a Visualizer feature that would be helpful for this purpose, which can be [accessed online](https://xstate.js.org/viz/) and [run locally](https://github.com/statecharts/xstate-viz).

That’s all for the intro post. Check out the next post to see more of the XState Visualizer!

---

## Bonus Track

XState is created by David Khourshid, who is a pianist and uses the handle [@DavidKPiano](https://twitter.com/DavidKPiano) online. It would be unacceptable if I did not use this opportunity to post this song called “Piano”! 🎹💃🏽

{% youtube RekVQE1fOBk %}

---

## References

* [XState Docs](https://xstate.js.org/docs/)
* [Welcome to the world of Statecharts](https://statecharts.github.io/) by Erik Morgensen
* [Guidelines for State Machines and XState](https://kyleshevlin.com/guidelines-for-state-machines-and-xstate) by Kyle Shevlin
* [Implementing a simple state machine library in JavaScript](https://kentcdodds.com/blog/implementing-a-simple-state-machine-library-in-javascript) by Kent Dodds

Talks by David Khourshid, XState creator:
* [ReactiveConf 2018 – David Khourshid: Reactive State Machines and Statecharts](https://www.youtube.com/watch?v=DrHccvns-L0)
* [David Khourshid: Simplifying Complex UIs with Finite Automata & Statecharts | JSConf Iceland 2018](https://www.youtube.com/watch?v=RqTxtOXcv8Y)
* [David Khourshid - Reactive State Machines and Statecharts - Uphill Conf 2019](https://www.youtube.com/watch?v=GSHQFx7PG20)

Live coding videos:
* [Let’s learn state machines with David K. Piano! — Learn With Jason](https://www.youtube.com/watch?v=czi24DqUfSA)
* [Fun Fun Function - XState: Let’s pair program state machines and state charts with David Khourshid](https://www.youtube.com/watch?v=uRfQJJArZEg)