Getting started with XState

Table of contents What is XState? Why should you use XState? Create a state machine Consume the machine Conclusion What is XState? XState is a state machine, often described as a state orchestrator. Sound unfamiliar? Let’s break it down. A state machine is similar to other state management solutions, but it’s unique in how it handles state. Unlike traditional approaches where you can assign any value at any time, a state machine exists in only one state at a given moment. To transition to a new state, specific conditions—such as events or rules defined in advance—must be met. Why should you use XState? While working on a project did you ever feel like, "The conditions are too complex to handle with simple if-else"? If so, then XState is your best choice here. As mentioned perviously, it let's you be in a specific state at a given moment, if you meet the criteria, there is little to no chance to mess it up once configured properly. From one step to another step, there's going to be specific rules. and also from one state you can only transition to another specified state. example: Let's say you have 3 states. A, B and C. Now the transitions are as follows: A -> C. B -> C. C -> B -> A. C -> A. Let's break down these transition For 1, You can only visit from A to C. For 2, You can visit from B to C. For 3 and 4, You can visit from C to B then from B to A. or from C to A. Let's see it visually stateDiagram-v2 [*] --> A A --> C: TO_C B --> C: TO_C C --> B: TO_B B --> A: TO_A C --> A: TO_A Now, if I ask you to write a logic to implement these transitions and safe guard the other states based on the current state using XState, you will immediately start feeling the heat. Although it is achievable by only using if-else, it's going to be really easy to make mistakes and hard to maintain once you start to add more and more states. But with XState it's going to be not very easy but not hard at all considering the complex logics. Now, to answer the question, if you have complex logics then you should go for solutions like XState, etc. And if not, then you are good with simple if else. Create a state machine Now let's create a simple state machine using XState to solve the problem. This is how it will look like. import { createMachine } from 'xstate'; const stateMachine = createMachine({ id: 'example', initial: 'A', states: { A: { on: { TO_C: 'C' } }, B: { on: { TO_C: 'C', TO_A: 'A' } }, C: { on: { TO_B: 'B', TO_A: 'A' } } } }); Now, let's try to understand what's happening here. Firstly you have to import the createMachine function from the xstate package. A machine must have an id and an initial state. Initial state defines from where the machine starts it's journey. Then you have to add the states. In this case, there can will be 3 states, A, B and C. Now define the transitions. You have to define your transitions within the on object. As per the problem, the transitions are defined here. Consume the machine Here's how you can consume it. import { interpret } from 'xstate'; const service = interpret(stateMachine) .onTransition((state) => { console.log(`Current state: ${state.value}`); }).start(); console.log('Sending events...'); // Test transitions, service.send('TO_B'); // A → B (fails, stays in A,) service.send('TO_C'); // A → C service.send('TO_B'); // C → B service.send('TO_A'); // B → A service.send('TO_B'); // A → B (fails again) service.send('TO_C'); // A → C service.send('TO_A'); // C → A The solution here shows you how you can consume it in vanilla javascript. You use the interpret function that returns the service. and then start it. After that from your code you can use the send method from the service to transition to any state. Here are all the transitions from our problem also a failed transition, from A -> B. There's no transition defined in the machine to visit B from A directly. So, whenever you try to visit the state directly, it's going to fail. Only the transitions that are valid are going to be successfully executed. Conclusion I hope I was able to give you a quick sneak peak of XState and help you understand it's potential. Also help you understand if you should use it or not and when should you use it. This example shows only the bare minimum power of XState. There's more that you can do with it.

May 6, 2025 - 03:16
 0
Getting started with XState

Table of contents

  • What is XState?
  • Why should you use XState?
  • Create a state machine
  • Consume the machine
  • Conclusion

What is XState?

XState is a state machine, often described as a state orchestrator. Sound unfamiliar? Let’s break it down.

A state machine is similar to other state management solutions, but it’s unique in how it handles state. Unlike traditional approaches where you can assign any value at any time, a state machine exists in only one state at a given moment. To transition to a new state, specific conditions—such as events or rules defined in advance—must be met.

Why should you use XState?

While working on a project did you ever feel like, "The conditions are too complex to handle with simple if-else"? If so, then XState is your best choice here. As mentioned perviously, it let's you be in a specific state at a given moment, if you meet the criteria, there is little to no chance to mess it up once configured properly. From one step to another step, there's going to be specific rules. and also from one state you can only transition to another specified state. example:
Let's say you have 3 states. A, B and C. Now the transitions are as follows:

  1. A -> C.
  2. B -> C.
  3. C -> B -> A.
  4. C -> A.

Let's break down these transition

  • For 1, You can only visit from A to C.
  • For 2, You can visit from B to C.
  • For 3 and 4, You can visit from C to B then from B to A. or from C to A.

Let's see it visually

stateDiagram-v2
    [*] --> A
    A --> C: TO_C
    B --> C: TO_C
    C --> B: TO_B
    B --> A: TO_A
    C --> A: TO_A

Now, if I ask you to write a logic to implement these transitions and safe guard the other states based on the current state using XState, you will immediately start feeling the heat. Although it is achievable by only using if-else, it's going to be really easy to make mistakes and hard to maintain once you start to add more and more states. But with XState it's going to be not very easy but not hard at all considering the complex logics.

Now, to answer the question, if you have complex logics then you should go for solutions like XState, etc. And if not, then you are good with simple if else.

Create a state machine

Now let's create a simple state machine using XState to solve the problem.

This is how it will look like.

import { createMachine } from 'xstate';

const stateMachine = createMachine({
  id: 'example',
  initial: 'A',
  states: {
    A: {
      on: { TO_C: 'C' }
    },
    B: {
      on: { TO_C: 'C', TO_A: 'A' }
    },
    C: {
      on: { TO_B: 'B', TO_A: 'A' }
    }
  }
});

Now, let's try to understand what's happening here.

  • Firstly you have to import the createMachine function from the xstate package.
  • A machine must have an id and an initial state. Initial state defines from where the machine starts it's journey.
  • Then you have to add the states. In this case, there can will be 3 states, A, B and C.
  • Now define the transitions. You have to define your transitions within the on object. As per the problem, the transitions are defined here.

Consume the machine

Here's how you can consume it.

import { interpret } from 'xstate';

const service = interpret(stateMachine)
  .onTransition((state) => {
    console.log(`Current state: ${state.value}`);
  }).start();

console.log('Sending events...');

// Test transitions,
service.send('TO_B'); // A → B (fails, stays in A,) 
service.send('TO_C'); // A → C 
service.send('TO_B'); // C → B 
service.send('TO_A'); // B → A
service.send('TO_B'); // A → B (fails again)
service.send('TO_C'); // A → C 
service.send('TO_A'); // C → A

The solution here shows you how you can consume it in vanilla javascript. You use the interpret function that returns the service. and then start it. After that from your code you can use the send method from the service to transition to any state. Here are all the transitions from our problem also a failed transition, from A -> B. There's no transition defined in the machine to visit B from A directly. So, whenever you try to visit the state directly, it's going to fail. Only the transitions that are valid are going to be successfully executed.

Conclusion

I hope I was able to give you a quick sneak peak of XState and help you understand it's potential. Also help you understand if you should use it or not and when should you use it. This example shows only the bare minimum power of XState. There's more that you can do with it.