v2.2What's new in the changelog →
Your state is a living tree.
Mutable, protected models on the inside. Snapshots, JSON patches and replayable actions on the outside. Powered by MobX, typed end to end.
ACTIONSonActionMiddleware
PATCHESonPatches
SNAPSHOTgetSnapshot(store)
{
todos: [],
$modelType: "todo/Store"
}Write plain actions. Get the rest for free.
Getting started guide →YOU WRITETodo.ts
@model("todo/Todo") class Todo extends Model({ text: prop<string>(""), done: prop(false), }) { @modelAction toggle() { this.done = !this.done } }
YOU GET · SNAPSHOTSgetSnapshot(todo)
{ text: "Write docs", done: true, $modelType: "todo/Todo" }YOU GET · TYPESSnapshotOutOf<Todo>
{ text: string; done: boolean; … }YOU GET · PATCHESonPatches(todo, …)
[{ op: "replace", path: ["done"], value: true }]YOU GET · REPLAYABLE ACTIONSonActionMiddleware(store, …)
{ actionName: "toggle", args: [], targetPath: ["todos", 1] }YOU GET · UNDOundoMiddleware(store)
undoManager.undo() // done → falseYOU GET · RESTOREfromSnapshot(Todo, sn)
const copy = fromSnapshot(Todo, sn) copy.toggle() // a live, typed Todo
YOU GET · PROTECTIONtodo.done = true
// throws: data changes must be performed inside model actionsYOU GET · TREEgetParent(todo) · getRoot(todo)
getParent(todo) // store.todos getRoot(todo) // store
MIDDLEWARES
Time travel built in
Undo/redo, transactions, read-only guards and your own action middlewares.
REFERENCES
Links that stay valid
First-class references between nodes, resolved as the tree changes.
TYPESCRIPT
Inferred, not declared twice
Models, snapshots and actions typed from one definition.
RUNTIME TYPES
Checked when it matters
Opt into runtime type checking per prop with tProp.
CRDT
Y.js & Loro bindings
Collaborative, offline-friendly state with the same models.
Loved by the people who use it
It's taken all the best bits from mobx and mobx-state-tree and put them into a single package that's a joy to work with.
@robclouthon issue #146After evaluating every state library out there, mobx-keystone stands out.
@lolmauson issue #566mobx-keystone is awesome and way easier to use for typesafe domain modeling than MST.
@krnsk0on issue #467