How does MobX compare with Redux and which one is better for React app development?

View other answers to this thread
Start a personal dev blog on your domain for free and grow your readership.

3.4K+ developers have started their personal blogs on Hashnode in the last one month.

Write in Markdown · Publish articles on custom domain · Gain readership on day zero · Automatic GitHub backup and more

Lorefnon's photo

MobX and Redux try to solve the similar problem using different approaches. The crux of the objective being; state management in javascript applications.

The core problem here is effective and optimal synchronization of information between your primary data source and the user interface, through whatever layers and transport mechanisms you have in between.

@saiki has already written a great comparative analysis rich with examples, which helps you understand what code would look like when written using MobX vs Redux.

What follows is a high level take on their pros and cons based on my personal experience:

MobX embraces an approach often called Declarative MVVM:

You declare how your application state should look like. You declare how your user interface depends on the application state. And you declare how user interactions against your user interface map to state change.

The data binding mechanism (usually opaque from application author's perspective) updates your user interface as and when necessary when application state changes. When a user interacts with the application, the framework updates your application state. These operations may result in effects/reactions, which essentially provide you hooks for doing things you can't do declaratively.

MobX change of flow

This paradigm itself is not new and libraries like Knockout.js have adopted a similar approach from a long time.

title here

However, Mobx does manage to elegantly address many of problems I faced on an almost everyday basis working with Knockout:

  • Framework-specific data wrappers: You don't write your business logic coupled with framework specific data structures. Yes, you have to annotate with @observer and @obversable but while writing the code where most of the logic resides you can pretend to be dealing with plain javascript objects.

  • Synchronous change propagation: This is very helpful because you don't end up getting lost about what changed because of what in a complex graph of dependencies.

  • Good dev-tools: This is a big pro as they allow you to visualize the dependency graph, and what all would/did change in the application state as well as in the user interface, because of some change in some node.

Redux embraces functional programming and referential transparency:

State is a plain javascript object. You never mutate it directly, but instead, derive a new updated state when something happens in the application (which result in action dispatch) through pure functions.

From a very comprehensive introductory presentation by Nikolaus Graf:

Redux Flow

Redux can leverage the constraints around immutability to guarantee predictability.

By religiously adhering to the unidirectional flow of data, many errors that arise due to mismanagement of complex dependencies in data entities are eliminated. Also, you get some great side-benefits like Hot reloading and time travel that developers simply did not expect until redux showed up.

The author has succinctly summarized the advantages of this approach here

Neither of them is a silver bullet.

MobX synchronously (though optimally) updates the dependency graph by intercepting accessors. This implies that your assumptions about algorithmic complexity when mutating object properties, or pushing things into arrays are no longer valid. The supplementary dev-tools are there to help, but you have to know where to look, as a lot is tucked underneath elegant abstractions. People have often resorted to the word magic for describing APIs like this.

Redux has been criticised for being verbose. But apart from that, there is also a tendency for the code written against side-effect management libraries like redux-thunk or redux-saga (which is where most of the business logic would reside) to get closely coupled with the framework ecosystem and the opinions these utility authors bring with them.

Yes, you are writing just referentially transparent functions, but these functions are written in the context of expectations set by the library. With MobX much of your code is written behaving as though you are just mutating vanilla javascript objects - I have found this to be very helpful from a purely pragmatic standpoint.

This especially makes things like code review and integration harder when people under the same roof end up using different variants of flux or different side effect management libraries (which would inevitably happen given the churn in js ecosystem).

Fowler's warning about CQRS are very much applicable to Flux/Redux as well, as the two are very closely related:

Despite these benefits, you should be very cautious about using CQRS. Many information systems fit well with the notion of an information base that is updated in the same way that it's read, adding CQRS to such a system can add significant complexity. I've certainly seen cases where it's made a significant drag on productivity, adding an unwarranted amount of risk to the project, even in the hands of a capable team. So while CQRS is a pattern that's good to have in the toolbox, beware that it is difficult to use well and you can easily chop off important bits if you mishandle it.

Having said all the above, MobX is certainly easier to get started with and to manage in small to medium scale applications. While Redux is intended primarily for really large applications written by big teams, it is much more explicit and once you train yourself think around unidirectional flow of data, is much easier to reason about, without needing help from special tools.

Sai Kishore Komanduri's photo

If you're not acquainted with CQRS, and want to delve into something which would give you a better understanding, then this video is a great resource.

You should be able to make the Redux-CQRS connection easily after watching the above video. And of course, the GitHub issue shared by @lorefnon sure does shed more light on this. Not considering accuracy; this comment puts it concisely!