Skip to content

/web-state-mobx

MobX observable state management patterns with mobx-react-lite. Use when implementing reactive client state with observables, computed values, actions, and the observer HOC.

shell
$ npx -y skills add agents-inc/skills --skill web-state-mobx --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.
  • You can call itInvoke it directly when you want it.
  • Slash command/web-state-mobx
How auto-invocation works

Context preview

The summary Claude sees to decide when to auto-load this skill.

MobX observable state management patterns with mobx-react-lite. Use when implementing reactive client state with observables, computed values, actions, and the observer HOC.

SKILL.md

web-state-mobx.SKILL.md
name: web-state-mobx
description: MobX observable state management patterns with mobx-react-lite. Use when implementing reactive client state with observables, computed values, actions, and the observer HOC.

MobX State Management Patterns

> **Quick Guide:** Use MobX for complex client state needing automatic dependency tracking, computed values, and fine-grained reactivity. Use `makeAutoObservable` for stores, `observer` from `mobx-react-lite` for React components, and `runInAction`/`flow` for async state updates. Never use MobX for server state -- use your data-fetching solution instead.

---

<critical_requirements>

CRITICAL: Before Using This Skill

> **All code must follow project conventions in CLAUDE.md** (kebab-case, named exports, import ordering, `import type`, named constants)

**(You MUST call `makeAutoObservable(this)` in EVERY class store constructor - or use `makeObservable` with explicit annotations for subclassed stores)**

**(You MUST wrap ALL state mutations after `await` in `runInAction()` - or use `flow` with generator functions instead of async/await)**

**(You MUST wrap EVERY React component that reads observables in `observer()` from `mobx-react-lite`)**

**(You MUST always dispose reactions (autorun, reaction, when) to prevent memory leaks)**

</critical_requirements>

---

**Auto-detection:** MobX, makeAutoObservable, makeObservable, observable, observer, mobx-react-lite, runInAction, flow, computed, autorun, reaction, useLocalObservable

**When to use:**

  • Complex client state with computed derivations and automatic dependency tracking
  • Class-based or factory-function stores with observable properties
  • Fine-grained reactivity where only affected components re-render
  • State that benefits from transparent reactive programming (spreadsheet-like derivations)

**When NOT to use:**

  • Server/API data (use your data-fetching solution)
  • Simple local UI state (use `useState`)
  • Lightweight shared state without computed needs (simpler state solutions exist)
  • State that should be URL-shareable (use `searchParams`)

---

<philosophy>

Philosophy

MobX embraces a core principle: **"Anything that can be derived from the application state, should be derived. Automatically."** It uses transparent reactive programming where observables track dependencies at runtime and only notify exactly the computations and components that depend on changed values.

MobX uses mutable observables with automatic tracking. This means less boilerplate than immutable/reducer-based approaches but requires understanding how reactivity works -- specifically, MobX tracks property access during tracked function execution, not variable assignments.

When to Use MobX

  • Complex domain models with many derived/computed values
  • Applications where class-based stores provide natural organization
  • Scenarios requiring fine-grained reactivity (large lists, frequent updates)
  • Teams comfortable with mutable state and OOP patterns

When NOT to Use MobX

  • Server state management (use your data-fetching solution)
  • Simple shared UI state without derivations (lighter alternatives exist)
  • Projects preferring immutable state patterns
  • Simple component-local state (`useState` is sufficient)

</philosophy>

---

<patterns>

Core Patterns

Pattern 1: Store Creation with makeAutoObservable

`makeAutoObservable` infers annotations automatically: properties become `observable`, getters become `computed`, methods become `action`, and generator functions become `flow`. It cannot be used on classes with `super` or that are subclassed.

class TodoStore {
  todos: Todo[] = [];
  filter: "active" | "completed" | "all" = "all";

  constructor() {
    makeAutoObservable(this); // auto-infers all annotations
  }

  get activeTodos(): Todo[] {
    return this.todos.filter((todo) => todo.status === ACTIVE_STATUS);
  }

  addTodo(title: string): void {
    this.todos.push({ id: crypto.randomUUID(), title, status: ACTIVE_STATUS });
  }
}

Use `autoBind: true` option to auto-bind methods for safe callback passing. Pass overrides as second argument to exclude properties (e.g., injected dependencies) from observability.

See [examples/core.md](examples/core.md#pattern-1-store-creation-with-makeautoobservable) for complete examples with autoBind and overrides.

---

Pattern 2: Store Creation with makeObservable

`makeObservable` requires explicit annotation of each property. **Required** for classes using `extends` (inheritance) -- `makeAutoObservable` throws on subclasses.

class BaseEntityStore<T extends Entity> {
  entities: T[] = [];

  constructor() {
    makeObservable(this, {
      entities: observable,
      entityCount: computed,
      addEntity: action,
    });
  }

  get entityCount(): number {
    return this.entities.length;
  }
}

See [examples/core.md](examples/core.md#pattern-2-store-creation-with-makeobservable) for base/subclass examples.

---

Pattern 3: Factory Function Stores

Factory functions with `makeAutoObservable` avoid `this` and `new` complexity, compose easily, and can hide private members via closures.

function createTimerStore(): TimerStore {
  return makeAutoObservable({
    secondsPassed: INITIAL_SECONDS,
    get minutesPassed(): number {
      return Math.floor(this.secondsPassed / SECONDS_PER_MINUTE);
    },
    tick(): void {
      this.secondsPassed++;
    },
  });
}

See [examples/core.md](examples/core.md#pattern-3-factory-function-stores) for typed factory examples.

---

Pattern 4: React Integration with observer

The `observer` HOC from `mobx-react-lite` makes React components reactive. It automatically tracks which observables are read during render and re-renders only when those specific values change. `observer` auto-applies `React.memo`.

// observer tracks observables read during render
const TodoList = observer(function TodoList() {
  return (
    <ul>
      {todoStore.
Read more
Read it on GitHub ↗

Showing the first part of this file.

Ships withagents-inc-skills

The official skills marketplace for Agents Inc. 150+ skills covering everything from React and Prisma to Redis, ElevenLabs, and infrastructure tooling. Pick the skills that match your stack and install them via Claude Code. Need more control?

Get the whole plugin, auto-invoked