Property reads decide which parts of the screen update
Change an observable field and MobX updates the code that depends on it. The README's timer example makes the relationship tangible: an observer component reads secondsPassed, and an action changes that field. You don't maintain a separate list of dependencies for that view. This is an appealing fit for an editor or planning tool where several screens derive their display from the same changing objects.
Our 415-file checkout contained roughly 105,407 source lines and occupied 13.5 MB before installation. That is the development repository, including workspace packages, rather than the size of MobX inside your app. Its MIT license and separation from any particular UI framework make it reasonable to evaluate around existing domain objects. The adoption decision is whether your team prefers runtime tracking enough to learn its boundaries.
What happened when we ran it
Our sandbox installed commit 457ea8f in 102 seconds, adding 2,621 packages and occupying 676 MB on disk. The build passed in 45 seconds. Jest succeeded in 53 seconds, reporting 1,306 passed, 0 failed, and 14 skipped out of 1,320 tests. We ran it on October 10, 2026, with Node 22, 3 CPUs, and 8 GB of RAM in an unprivileged Debian container without secrets.
The 676 MB environment belongs to our repository install. It doesn't measure an application's download size, memory use, or rendering speed. Our scan found monorepo workspaces and 3 CI workflow files, with no Dockerfile or tests directory. That directory signal plainly doesn't mean the project lacks tests: the supplied Jest result records the suite we ran. The build and test successes are useful evidence that the checkout was workable. Npm audit reported 122 known vulnerabilities: 11 critical, 54 high, 53 moderate, and 4 low. The supplied summary doesn't identify affected packages or distinguish development tools from production dependencies. I wouldn't call MobX itself remotely exploitable from that count. I also wouldn't accept a clean-build argument for ignoring it. A team working in this checkout needs to inspect the dependency paths before approving its environment.
A value read after await falls outside tracking
MobX's reactivity guide says tracking follows observable properties read during a tracked function's execution. A read inside a later promise callback or after await falls outside that execution. Copying a property's value before entering the function can also leave the function watching a plain value. These are specific ways to get a stale display even though changing the original object looks correct.
The 1,306 passing tests in our run support the tested implementation, but they don't teach a new teammate where their own reads happen. I would evaluate MobX with a small feature that includes a delayed response and a derived display. Ask someone other than its author to explain why each view updates. If that explanation repeatedly depends on trial and error, automatic tracking may cost your team more than it saves.
Async writes and manual reactions need explicit care
Actions group related state changes so reactions don't see intermediate values before the outer action finishes. An async function resumes outside that original action after await, so subsequent changes need their own action boundary, such as runInAction. This is a practical distinction for loading a record: the response can arrive correctly while your state-update code still violates the intended action discipline.
MobX's reaction documentation also tells you to dispose of manual reactions when they're no longer needed. Our 53-second Jest result isn't a memory-retention experiment for a long-lived application. If you add subscriptions when a document opens, decide who releases them when it closes. Computed values are preferable when you only need a derived answer, because a manual side effect adds a lifecycle responsibility.
React integration extends beyond adding observer
The official React integration guide requires observable reads to happen inside observing components. Passing an observable object to a component that doesn't observe it can leave updates unseen there. Function components use mobx-react-lite, while class-component support uses mobx-react. Server rendering has its own setting, enableStaticRendering(true). These distinctions matter when an existing app mixes third-party widgets, older class components, and server-rendered pages.
The 2,621-package install we measured gives no guarantee about that mix in your project. The configuration guide now warns that React's development performance tracks can trigger noisy observableRequiresReaction warnings. Its current Proxy requirement is another concrete boundary for older JavaScript environments. Read the host requirements before a migration, and use the documented earlier MobX route if you must support a runtime without Proxy support.
October fixes show maintenance of subtle behavior
The last push was October 11, 2026, and GitHub showed 28,208 stars with 35 open issues and PRs. The latest release, mobx@7.0.6, shipped on October 2. Its notes describe fixes for intercepted observable-array length changes and abort listeners retained by disposed reactions. Recent issue activity included React development warnings and documentation updates. These are concrete maintenance signals, rather than a conclusion drawn from the star count alone.
Redux Toolkit is my preference when a team wants shared reducer and action conventions. Zustand fits a React store with explicit selection, while Valtio offers another proxy-based approach. MobX earns a trial when mutable domain objects and derived views are central to the app. Budget for the 676 MB contributor environment we measured, review its audit findings, and make your first feature include an async update and subscription cleanup.

