You Don’t Need Redux, MobX, RxJS, Cerebral

For state management, try this simple pattern instead of a library

Don’t get me wrong. Those libraries are great. But I’m suggesting a different, unique approach.

I know what you’re thinking: Redux alternatives are a dime a dozen. But this isn’t yet another library. In fact, it’s not a library at all.

It’s just a simple pattern: Meiosis.

Why a Pattern?

Using a pattern instead of a library means that you have more freedom. You are not dependent on a library’s features, bugfixes, and release dates. You are not worried about backward compatibility, deprecation, upgrade migration paths, or project abandonment. You are never waiting for a missing feature.

No More Black Box

Sometimes when using a framework or library, you get that uneasy “black box” feeling where you stop knowing what’s happening with your code. You call a framework function, something magical happens in the black box, and out comes the result. If the result is unexpected, you have to start searching for answers, or (gasp) digging into the framework’s source code.

With Meiosis, you can easily follow everything that is happening with the code. Because there is no black box. You can fully and completely implement the pattern from scratch, so you know exactly what the code is doing. There is no mystery. You get that satisfying feeling of being in control, of understanding how all of the code works.

No Library Lock-In

Using a pattern means that you are not tying your state management code to a library-specific API. No more annotations, wrapping in proprietary objects, using a dozen different stream operators, or piling up plugins, middleware, and other dependencies.

Instead, Meiosis is based on first principles: use plain JavaScript objects and functions to manage state in your web application. No import or require of a state management library.

This also means that you can achieve the equivalent of such things as React Context and Render Props without having to use React or even needing to upgrade your version of React to use these types of features.

Less Boilerplate

No more action constants, if/else or switch statements, providers, connectors, thunks, sagas, annotations, mappers, etc.

No special code needed for asynchronous actions!

Use with any virtual DOM library

It is very simple to use the Meiosis pattern with any virtual DOM library: React, Preact, Inferno, Mithril, Snabbdom, and so on. Other view libraries such as lit-html and hyperHTML work just as well.

All you need to know is the library’s function to render/re-render into a DOM node. For example, with React this is ReactDOM.render. So really it’s one line of code that sets up the pattern with a view library.

So What is the Meiosis Pattern?

The Meiosis pattern is a reactive loop, illustrated below:

Meiosis Reactive Loop
  • We start with a model, which is a plain JavaScript object. This represents our application state.
  • Then, we have a view, which is a function of the model that produces a virtual-DOM node suitable for our chosen view library to render. Above, you can see that with React, this would be ReactDOM.render.
  • When an event happens, such as the user clicking on a button, we call an update function to produce an updated model.
  • The view is automatically re-rendered, by calling view and ReactDOM.render.

What Do We Gain?

By using the Meiosis pattern, we reach some important goals in implementing a web application:

  • We have a single root model. This is our application state, as a plain JavaScript object. This is our single source of truth.
  • The view is a function of the model. The view can be fully determined from the model.
  • We have a controlled, well-defined way to update the model.
  • Updating the model automatically re-renders the view. Because we implement the pattern ourselves, we know exactly how this works.

Implementing the Meiosis Pattern

The Meiosis Pattern can be implemented in different ways. First, you decide how you want to implement the reactive loop, and second, you choose how to structure model updates.

For most of the examples, I implement the reactive loop with a simple, minimal stream library. I only use map and scan, and I only use them in one place. You do not have to use stream operators anywhere else in the application!

However, you can also implement a bare-bones map and scan from scratch with just a handful of lines of code, and that is sufficient to implement the Meiosis Pattern.

I explain all of this in the Meiosis Tutorial.

Time-Travel Tool: The Meiosis Tracer

Meiosis is not a library. However, Meiosis does include a time-travel debugging tool, called the Meiosis Tracer. If you are already using a time-travel tool, know that you don’t have to abandon that possibility when using Meiosis.

You can see an example of the tracer below. Notice how you can not only trace back and forth through the history of application states, you can even directly type in a model and see the resulting view.

Routing Example — With Time Travel!

This example also demonstrates that routing can be implemented with Meiosis such that the application state still fully determines the view, including the route in the location bar.

Yes, You Can Do That With Meiosis

Meiosis is a simple pattern. Beyond that, Meiosis is documentation and examples to show how to achieve useful features in web application development:

  • Computed properties
  • Reusable components as plain objects with functions
  • Nesting component models within the single state object
  • Routing
  • Render Props equivalent
  • React Context equivalent
  • Using view library lifecycle methods
  • Imperative widgets (Bootstrap, jQuery, …)
  • Preventing re-renders of unchanged components
  • and so on.

Try It Out

You can learn the Meiosis pattern with the Meiosis Tutorial. Once you are comfortable with the pattern, you can learn more techniques by visiting the Meiosis Wiki.

Give it a try. I hope you find it useful!