mobx.dart: reactive state management for Dart and Flutter
MobX for the Dart language. Hassle-free, reactive state-management for your Dart and Flutter apps.
At a glance
- What is it?
- mobx.dart ports MobX's observable-action-reaction model to Dart, with code generation to cut the boilerplate. It suits Flutter apps with derived state that must stay in sync; it is a poor fit if you want hand-written, annotation-free stores.
- Who is it for?
- Adopt mobx.dart if your Flutter state is a tree of values that other values derive from, and you accept a build_runner step in exchange for not writing getters by hand. Skip it if you want stores with no generated code, or if your state is a handful of fields a single ChangeNotifier already covers.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 12 days ago.
- What is it written in?
- Mainly Dart, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 28, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What mobx.dart solves, and who it is for
The README frames the problem plainly: connecting reactive data to the UI, with the wiring done automatically. In a Flutter app, the tedious part of state management is not holding a value, it is remembering every place that value feeds into and updating each one when it changes. mobx.dart makes that tracking the library's job. You mark what is observable and where it is consumed, and the re-run happens for you. The stated audience is Dart and Flutter developers, and the project describes itself as a port of the JavaScript MobX library, so anyone coming from the JS ecosystem will recognise the model. The README also notes the project is looking for maintainers, which is worth knowing before you build a large store layer on it. The last push to the default branch was on 2026-09-18, so the repository is not dormant, but the most recent release listed is mobx_lint 1.0.0 and mobx_codegen 2.5.0, both from 2023-12-27.
Observables, actions and reactions as the mechanism
The README describes three concepts at the heart of the library: observables, actions and reactions. Observables hold the reactive state, from a single scalar to a tree of objects. Actions are the mutations. Reactions are the consumers, and the README says a reaction can be anything from a console log to a network call to a UI re-render. The data flow is one-directional: an action changes an observable, and every reaction that read that observable re-runs. The library tracks which reaction read which observable, so you do not register listeners yourself. Computed observables sit on top of that: the README's phrasing is that what can be derived should be derived, splitting your state into core-state and derived-state. A computed value is not stored, it is recalculated from the observables it reads. That distinction matters in practice, because a derived value can never drift out of sync with its inputs, but it also means a computed that reads a large observable tree is recomputed whenever any part of that tree changes.
Installing mobx.dart and writing a first store
The README does not carry install commands. It points to the Getting Started guide on the MobX.dart website, and the repository layout shows three published packages: mobx, flutter_mobx and mobx_codegen, each with a badge for its pub.dev page. The README's own example is the codegen form of a counter, and it is the shortest path to a working store. The annotations come from mobx_codegen, and the generated file is wired in with a part directive.
import 'package:mobx/mobx.dart';
part 'counter.g.dart';
class Counter = CounterBase with _$Counter;
abstract class CounterBase with Store {
@observable
int value = 0;
@action
void increment() {
value++;
}
}After adding the dependency, the counter.g.dart file is produced by build_runner, the standard Dart code generation step. Until that file exists, the part directive points at nothing and the class will not compile. That is the first thing a new user hits, and it is why the README spends a paragraph explaining that the header boilerplate is fixed for any class. Once the store exists, flutter_mobx supplies the widgets that observe it, which is where the reactions that re-render the UI come from.
The mobx_codegen trade-off
The README is candid that the hand-written version of a store is boilerplate that can get out of hand, and shows the alternative: a private Observable field, a getter, a setter and an Action wired up in the constructor. For a two-field class that is tolerable. For a class with twenty fields it is not, which is the argument for mobx_codegen. The cost is that a build step now sits between your source and a compiling app. Generated files have to be regenerated when the store changes, they are typically excluded from version control, and a stale counter.g.dart produces errors that point at generated code rather than at your edit. There is also a smaller convenience in the README worth knowing: swapping @observable for @readonly generates a public getter for a private variable, so clients of the store can read the value but not assign it. That is a code-generation trick, not an access-control feature of the language, so it only applies to fields you annotate.
Where mobx.dart is the wrong choice
If your app's state is a few fields that a single ChangeNotifier already handles, adding mobx.dart buys you a dependency, an annotation layer and a code generation step to replace code you were not struggling to write. The README's own before-and-after example is the clearest evidence: the manual version is short, and the library's justification for codegen is complexity that arrives later. The other boundary is the build step itself. Teams that keep generated code out of their pipeline, or that run in an environment where build_runner is awkward, will feel the friction on every store change. And because computed values are derived rather than stored, a computed that reads a wide observable tree recalculates whenever any part of that tree changes; the library's model does not give you a way to freeze a derived value at a point in time. The README does not document rollback or migration paths between major versions, so if you are upgrading an existing store layer, the CHANGELOG is the place to look rather than the README.
mobx.dart against Redux-style state containers
The obvious comparison is Redux, and the README does not make it, so the difference has to be read off the mechanism. A Redux-style store keeps one state tree and changes it by dispatching actions to a reducer; every subscriber is notified and decides for itself whether the state it cares about changed. mobx.dart inverts that. There is no single tree and no dispatch. Each observable is tracked individually, and only the reactions that actually read a changed observable re-run. That is the practical difference: Redux pushes the diffing to your selectors, mobx.dart does the tracking at the property level. The cost of mobx.dart's approach is that the tracking is implicit. There is no action log to replay, and the README does not describe time-travel debugging or state snapshots, so if you need a reproducible sequence of state transitions, a reducer-based container gives you that by construction and mobx.dart does not.
Maintenance, licence and upgrade cost
The repository is not archived, and the last push to the default branch was on 2026-09-18. The release list is older than that: mobx_lint 1.0.0, mobx_codegen 2.5.0 and mobx_codegen 2.4.1 all date from 2023-12-27. Those two facts together describe a project whose repository sees activity but whose published packages have not moved recently, and the README's note that maintainers are being sought is consistent with that. Plan for a store layer you may have to carry yourself. The licence is MIT, which is permissive and places few obligations on how you distribute a Flutter app that depends on it; that is a statement about the licence text, not legal advice, and if your organisation has licence review, run it through that. On upgrade cost, the codegen package is the piece most likely to need attention, because it depends on build_runner and the analyzer, and changes in those tools can force a mobx_codegen upgrade independently of anything you changed in your stores. The README does not describe a migration procedure between versions.
Editorial conclusion
Adopt mobx.dart if your Flutter state is a tree of values that other values derive from, and you accept a build_runner step in exchange for not writing getters by hand. Skip it if you want stores with no generated code, or if your state is a handful of fields a single ChangeNotifier already covers. Before committing, verify that mobx_codegen runs cleanly on your Dart SDK and check the getting-started guide on the project site, since the README defers installation to it.
Frequently asked questions
What is mobx.dart used for?
It is a state-management library for Dart and Flutter that connects reactive data to the UI automatically. You mark observables and actions, and reactions re-run when the observables they read change.
What is the difference between Redux and mobx.dart?
A Redux-style store keeps one state tree and notifies every subscriber on dispatch, leaving each subscriber to decide what changed. mobx.dart tracks each observable separately, so only the reactions that read a changed observable re-run. The README does not describe time-travel debugging or state snapshots for mobx.dart.
Do I have to use mobx_codegen with mobx.dart?
No. The README shows a hand-written store using Observable, Action and a constructor that wires the action up. mobx_codegen exists to remove that boilerplate, and the annotations it provides are what the shorter example uses.
What does the part directive in a mobx.dart store refer to?
It points at the generated file, named after the store file, for example counter.g.dart for counter.dart. That file is produced by the code generation step, and the class will not compile until it exists.
What licence does mobx.dart use?
The repository is MIT licensed. That is the licence identifier recorded for the project; how it applies to your distribution is a question for your own licence review.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/mobxjs-mobx-dart)