What is an actual difference between redux and a state machine (e.g. xstate)?

Artem Arkhipov picture Artem Arkhipov · Feb 1, 2019 · Viewed 12.5k times · Source

I am working on investigation of one front-end application of medium complexity. At this moment it is written in pure javascript, it has a lot of different event-based messages connecting few main parts of this application.

We decided that we need to implement some kind of state container for this application in scope of further refactoring. Previously I had some experience with redux and ngrx store (which actually follows the same principles).

Redux is an option for us, but one of the developers proposed using a state-machine based library, in particular the xstate library.

I've never worked with xstate, so I found it interesting and started reading documentation and looking at different examples. Looked promising and powerful, but at some point I understood that I don't see any significant difference between it and redux.

I spent hours trying to find an answer, or any other information comparing xstate and redux. I didn't find any clear information, except some articles like "get from redux to a state machine", or links to libraries focused on using redux and xstate together (quite weird).

If someone can describe the difference or tell me when developers should choose xstate - you are welcome to.

Answer

David Khourshid picture David Khourshid · Feb 4, 2019

I created XState, but I'm not going to tell you whether to use one over the other; that depends on your team. Instead, I'll try to highlight some key differences.

  • Redux is essentially a state container where events (called actions in Redux) are sent to a reducer which update state.
  • XState is also a state container, but it separates finite state (e.g., "loading", "success") from "infinite state", or context (e.g., items: [...]).
  • Redux does not dictate how you define your reducers. They are plain functions that return the next state given the current state and event (action).
  • XState is a "reducer with rules" - you define legal transitions between finite states due to events, and also which actions should be executed in a transition (or on entry/exit from a state)
  • Redux does not have a built-in way to handle side-effects. There are many community options, like redux-thunk, redux-saga, etc.
  • XState makes actions (side-effects) declarative and explicit - they are part of the State object that is returned on each transition (current state + event).
  • Redux currently has no way to visualize transitions between states, since it does not discern between finite and infinite state.
  • XState has a visualizer: https://statecharts.github.io/xstate-viz which is feasible due to the declarative nature.
  • The implicit logic/behavior represented in Redux reducers can't be serialized declaratively (e.g., in JSON)
  • XState's machine definitions, which represent logic/behavior, can be serialized to JSON, and read from JSON. This makes behavior very portable and configurable by external tools.
  • Redux is not strictly a state machine.
  • XState adheres strictly to the W3C SCXML specification: https://www.w3.org/TR/scxml/
  • Redux relies on the developer to manually prevent impossible states.
  • XState uses statecharts to naturally define boundaries for handling events, which prevents impossible states and can be statically analyzed.
  • Redux encourages the use of a single, "global" atomic store.
  • XState encourages the use of an Actor-model-like approach, where there can be many hierarchical statechart/"service" instances that communicate with each other.

I will add more key differences to the docs this week.