Sakalim

Sakalim

About Me

January 13, 2024

Rethinking State Management - Why XState is a Game-Changer for Developers

8 min read

    beginnersjavascriptreacttutorial

In this article, I want to share a personal journey of discovery in the world of state management. My path led me to XState, a tool that I believe is the best choice for managing state in modern applications like React, Angular, Vue, and others. This isn't just a professional advice; it's a personal recommendation based on real-world experience.

It’s important for you to know that this advice is backed in my professional experience. Over the last twenty three years as a software developer, I’ve explored a variety of technologies and trends. For the past eight years, I've been part of the company Kaltura, leading front-end teams development. In the last four years, I’ve also stepped into the role of our group frontend architect. My journey has covered everything from hands-on development to architectural design, mentoring, leading teams, and code reviewing.

The purpose of sharing my background isn't to show off but to lend credibility to my views on XState. I firmly believe that XState is a critical tool for any application striving for maturity, robustness, sustainability, maintainability, and optimal performance.


A Personal Example: Kaltura Meeting Experience

It's important to note that XState is an excellent candidate for any size of application that requires more than just React context. Its adaptability makes it equally effective in small-scale projects as it is in large, complex applications. The reason XState hasn't been as widely adopted by the community, as I see it, is detailed later in the article.

In our work on the Kaltura Meeting Experience, we encountered significant challenges as the project expanded. Originally built using Redux, the application was initially impressive in its performance and capabilities. However, as the complexity increased with over 30 distinct features we hit the scalability wall. Each feature comes with its own set of logics, restrictions, states, and actions, we reached a point where we lost control over the application state.

xstate-kme-features-word-cloud.png (997×501) (sakalim.s3.us-east-2.amazonaws.com)

This growing complexity highlighted the limitations of our existing state management approach. The more features we added, the more we realized that managing a complex network of states and interactions with Redux was becoming unsustainable.

The transition to XState marked a pivotal moment in the project. It was more than just a switch in technology; it was a strategic shift in how we approached state management. XState's ability to handle a multitude of states and transitions elegantly made it an ideal choice.

The Challenge of Adoption

As I see it, the main reason developers often stick with tools like Redux and MobX is due to their accessibility. These libraries simplify the concept of a state machine, easing the initial learning process and concealing their complexities and limitations until the later stages of product development.

In contrast, XState, with its extensive capabilities and the nuances of integrating it into React applications, presents a more intimidating learning curve. For us, it took several months to fully grasp how a full-blown state machine functions while simultaneously figuring out the optimal way to manage multiple machines that needed to interact with each other and with React.

Another factor contributing to Redux's popularity is its well-known browser extension for dev tools, which allows developers to easily visualize the application state at any given moment. This convenience is part of what simplifies the onboarding process for Redux. Many developers may not realize the work done under the hood when they enable devTools: true while creating a store with configureStore. This level of integration and ease of use is something that XState's author might consider emulating. I'll delve into your options for similar functionalities with XState in the last section.

Despite these challenges, we recognized from the first day that XState was the right tool for our needs. We embraced the challenge, and today we can confidently state that it was worth every bit of effort and refactoring we invested. The results speak for themselves in the enhanced stability and scalability of our applications

When XState Might Not Be Ideal Choice

While XState is a powerful tool for state management, there are scenarios where other tools might be more suitable. Firstly, if your front-end predominantly mirrors server-side CRUD (Create, Read, Update, Delete) operations and doesn't have websocket based realtime updates, a library like react-query could be a more efficient choice. This is due to its specialized handling of server-state synchronization.

Secondly, for managing interactions between nested components – a situation often referred to as 'prop drilling' – React Context is typically the preferred method. It simplifies the process of passing data through multiple component layers without cumbersome prop forwarding.

In all other scenarios, once you become proficient with it, I advocate for XState. Its robustness in managing states makes it an invaluable asset in a developer’s toolkit.

TL;DR - Understanding XState

This section offers a brief overview of XState for those seeking a quick summary. While it won't provide detailed instructions on using XState, it will give you a clear understanding of its core concepts and why it's becoming increasingly popular in the development community

What is XState?

XState is a library for creating, interpreting, and executing finite state machines and statecharts in JavaScript. At its core, XState is about managing state in a predictable, scalable, and maintainable way. In simpler terms, think of it as a roadmap that guides how your feature behaves in response to various events or actions. Unlike traditional state management solutions that can become unwieldy as applications grow, XState provides a structured and visual way of handling state, making it easier to understand and manage complex scenarios.

xstate-machine_example.png (1008×848) (sakalim.s3.us-east-2.amazonaws.com)

Why XState?

XState allows developers to define states, transitions, and actions in a structured format. This approach not only brings clarity to the development process but also reduces bugs and improves maintainability. With XState, you can visualize these state transitions and interactions, which is invaluable for both development and debugging.

How XState Works

Imagine your feature as a machine that can be in different states, like 'loading', 'idle', 'error', or 'success'. XState manages these states and the transitions between them based on events. For instance, when a user clicks a button, the application might move from 'idle' to 'loading'. XState handles these transitions smoothly and predictably. Furthermore, it integrates seamlessly with popular frameworks like React, Vue, and Angular, making it a versatile choice for many developers.

First Steps with XState

Giving XState a fair chance requires patience and dedication. It's essential to invest time in understanding the concepts of state machines and becoming familiar with their components.

Learn XState from the Documentation

  1. Start by exploring the XState v5 documentation. Note that there is also documentation for the older XState v4. Ensure you're referring to the latest version for the most current information.
  2. Before integrating XState with React, it's crucial to grasp the fundamentals of state management and statecharts. Begin with the Core Concepts section to build a foundational understanding of XState's functionality.
  3. Take your time to understand each term. The Glossary page offers a comprehensive list of terms, each linked to its relevant section in the documentation for more in-depth understanding.
  4. Utilize the online studio to explore and analyze machines created by others and try designing your own machines.

Implement the First Feature

When ready to implement XState in a React application, start with a single feature. This helps you get a feel for the process.

In XState, you can design a single state machine for your entire application, managing different features with spawn machines. However, for frameworks like React and Angular, I recommend creating a separate machine for each feature. This approach, using multiple machines instead of a centralized one with spawns, simplifies interactions with these frameworks.

Pro Tip: To succeed with XState, having runtime visibility of the machines is crucial. However, this is a weak point as I see it in XState. As of the writing of this article, the Inspector section in their documentation is marked as TBD. Your options are:

  1. Follow the XState v4 documentation for machine inspection.
  2. Consider using an extension like XState Ninja, though I haven't personally used it.
  3. Develop an internal tool for your application. We did this to tailor inspectors to our needs, but it's not a necessity from the start. Consider this only if it becomes relevant.

Avoid Using Spawn Machines Initially

As you delve into the documentation, the concept of spawning machines may catch your attention. Spawning is typically used for managing parallel sub-flows, like handling multiple file uploads simultaneously, with each upload having its own state machine. It’s advisable to master the basics of XState implementation before moving on to more advanced concepts like spawning.

If you need assistance, feel free to join the XState Discord channel or leave a comment below for guidance.