Skip to content

What it is

MobX is a simple, scalable, and battle-tested state management library for JavaScript applications. It allows you to manage application state outside of components while keeping your UI automatically in sync with state changes.

MobX uses observables to hold state, actions to modify state, and reactions or observers to automatically update the UI. Computed values allow derived state to be calculated efficiently. MobX integrates seamlessly with React via the `observer` higher-order component or hooks.

Installation

npm install mobx mobx-react

Getting started

The smallest useful thing you can do with it, and what each part means.

Creating an observable store
import { makeAutoObservable } from 'mobx';

class CounterStore {
  count = 0;
  constructor() {
    makeAutoObservable(this);
  }
  increment() {
    this.count += 1;
  }
  decrement() {
    this.count -= 1;
  }
}

const counterStore = new CounterStore();
export default counterStore;
Defines a store with observable state and actions. `makeAutoObservable` automatically makes state observable and actions reactive.
Using MobX store in a React component
import { observer } from 'mobx-react';
import counterStore from './CounterStore';

const Counter = observer(() => (
  <div>
    <button onClick={() => counterStore.decrement()}>-</button>
    <span>{counterStore.count}</span>
    <button onClick={() => counterStore.increment()}>+</button>
  </div>
));
Wraps the component with `observer` so it re-renders automatically when `counterStore.count` changes.

Advanced usage

Where the library earns its place over a simpler alternative.

Computed values
import { makeAutoObservable } from 'mobx';

class CartStore {
  items = [];
  constructor() { makeAutoObservable(this); }
  addItem(item) { this.items.push(item); }
  get total() { return this.items.reduce((sum, item) => sum + item.price, 0); }
}

const cartStore = new CartStore();
Defines a computed value `total` that automatically recalculates when `items` change.
Reaction example
import { reaction } from 'mobx';
reaction(() => cartStore.total, total => {
  console.log('Cart total changed to:', total);
});
Sets up a reaction that triggers a callback whenever `cartStore.total` changes.
Asynchronous actions
import { makeAutoObservable, runInAction } from 'mobx';

class AsyncStore {
  data = [];
  loading = false;
  constructor() { makeAutoObservable(this); }
  async fetchData() {
    this.loading = true;
    const response = await fetch('/api/data');
    const result = await response.json();
    runInAction(() => {
      this.data = result;
      this.loading = false;
    });
  }
}
Demonstrates performing asynchronous operations safely with MobX using `runInAction`.

Errors and fixes

The failures you are most likely to hit, and what actually resolves them.

UI not updating
Ensure components using observables are wrapped with `observer` or use `useObserver` hook.
State mutation outside action
Enable `enforceActions` and make all state modifications inside actions.
Computed values not recalculating
Make sure computed properties access observable state and are not dependent on non-observable values.

Best practices

  • Use small, focused stores to manage state for different parts of the app.
  • Wrap React components with `observer` to automatically update UI when observables change.
  • Use `computed` for derived state to optimize performance.
  • Avoid directly mutating observables outside of actions for predictable behavior.
  • Leverage MobX DevTools for debugging and inspecting state changes.

Background

Why it exists, and what it was reacting to.

MobX was created by Michel Weststrate to provide a reactive state management solution that is less verbose and more intuitive than Redux. It leverages observables and derivations to automatically update UI components when state changes, reducing boilerplate and promoting a reactive programming paradigm.