mobx-utils

Utility functions and common reactive patterns for MobX, from Promise-to-observable bridging to lazy subscriptions.

Library
npm
v6.1.1
1,219stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
44/100Fair
Development Activity0
Maintenance0
Community76
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
77/100Good
Architecture74
Code Quality78
Innovation76
Learning Curve80

mobx-utils is the official companion library for MobX, providing a curated set of utility functions and patterns that solve problems developers repeatedly hit when building reactive applications on top of MobX’s observables and reactions. Rather than bloating MobX’s core with every conceivable helper, the MobX team split reusable patterns — tracking a Promise’s state as an observable, lazily subscribing to an external resource, or memoizing function calls by argument — into this separate companion package.

Because it is maintained by the MobX core team and versioned alongside MobX itself, mobx-utils is the de facto standard extension for MobX applications that need more than the bare observable/computed/autorun primitives, without pulling in a heavier framework-specific library.

What You Get

  • fromPromise / isPromiseBasedObservable — wraps native Promises as observables exposing pending/fulfilled/rejected state and a .case() handler for exhaustive rendering
  • lazyObservable / fromResource — observables that only subscribe to an external source when actually observed, with automatic teardown when unobserved
  • computedFn — memoizes a pure function’s output per unique argument set, backed by MobX’s computed/reactive invalidation
  • createViewModel — a mutable, revertible/committable wrapper for editing observable domain objects in forms without mutating the source until confirmed
  • deepObserve — recursively observes every property/array/map change within a nested observable tree via a single callback
  • queueProcessor / chunkProcessor — process items pushed onto an observable array individually or in batches as they arrive
  • moveItem, ObservableGroupMap, DeepMap and other observable-array and keyed-collection helpers

Common Use Cases

  • Tracking the loading/success/error state of an async fetch call directly as observable state, without hand-rolled boolean flags
  • Building an editable form around an observable domain object with commit/cancel/reset semantics via createViewModel
  • Deep-watching a nested observable store (for undo/redo, logging, or persistence) with deepObserve
  • Memoizing expensive per-item computations in a rendered list so unrelated array changes don’t recompute untouched items via computedFn
  • Subscribing an observable to an external, non-MobX data source (WebSocket, DB listener) only while it’s actually being rendered

Under The Hood

Architecture mobx-utils is organized as a flat collection of independent utility modules under src/ (from-promise.ts, lazy-observable.ts, from-resource.ts, computedFn.ts, create-view-model.ts, deepObserve.ts, queue-processor.ts, chunk-processor.ts, now.ts, ObservableGroupMap.ts, deepMap.ts, array.ts, expr.ts, create-transformer.ts, and shared utils.ts), each re-exported from a single barrel file, src/mobx-utils.ts. There is no shared runtime or class hierarchy tying the modules together — each utility independently calls into MobX’s public and a few low-level internal APIs (extendObservable, onBecomeUnobserved, onBecomeObserved, _isComputingDerivation, _getGlobalState) to hook into MobX’s observation lifecycle, which is how utilities like lazyObservable and computedFn detect when they stop being watched and can tear down or evict cached state.

Tech Stack The library is written in TypeScript (84% of the codebase) targeting compilation via tsc plus a Rollup bundle step (rollup.config.js) that produces UMD and ES module builds (mobx-utils.umd.js, mobx-utils.module.js) alongside .d.ts typings generated from src/. mobx (^6.0.0) is declared strictly as a peerDependency, not a runtime dependency, so the published package ships zero third-party runtime dependencies and simply extends whatever MobX instance the consuming application already has installed. Tests run under Jest with ts-jest; docs are regenerated via documentation.js straight from the JSDoc comments in the source and merged into the README’s API section.

Code Quality Test coverage lives in test/, with 10 dedicated spec files (plus Jest snapshot fixtures under test/__snapshots__) exercising the array helpers, computedFn, create-transformer, create-view-model, deepMap, deepObserve, ObservableGroupMap, and a type-tests.ts file that exercises the public type signatures. Source files are small and single-purpose (most under 150 lines), consistently documented with JSDoc @example blocks that double as the generated README API reference, and error paths route through a shared invariant/fail helper in utils.ts that throws prefixed, descriptive errors ([mobx-utils] ...) rather than failing silently.

API Design The public API is a flat set of standalone functions re-exported from one entry point, so consumers import exactly the utilities they need (import { fromPromise } from 'mobx-utils') with no class instantiation or setup boilerplate. Function names read as verbs/nouns that map directly to their behavior (fromPromise, fromResource, lazyObservable, deepObserve), and each is documented with the parameters, return shape, and a runnable example directly in the README, keeping the learning curve low for anyone already familiar with MobX’s own observable/computed/autorun vocabulary.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search