Todos
Pending: {store.pendingCount}
)
})
```
## 3. Know the core ideas
`mobx-keystone` feels easier once you know which primitive solves which problem:
| Need | Use |
| --- | --- |
| Mutable domain objects with actions and hooks | [Class Models](./classModels.mdx) |
| Backend-shaped data without `$modelType` in the payload | [Data Models](./dataModels.mdx) |
| Async actions | [Standard and Standalone Actions](./standardAndStandaloneActions.mdx) |
| App-level lifecycle and side effects | [Root Stores](./rootStores.mdx) |
| Serialization and persistence | [Snapshots](./snapshots.mdx) |
| Fine-grained change streams | [Patches](./patches.mdx) |
| Runtime validation | [Runtime Type Checking](./runtimeTypeChecking.mdx) |
## 4. Recommended next steps
Once the basic store is running, the next guides usually depend on what you need next:
- Want a deeper model walkthrough? Read [Class Models](./classModels.mdx).
- Need to persist or hydrate state? Read [Snapshots](./snapshots.mdx).
- Want undo/redo or interception? Read [Action Middlewares](./actionMiddlewares/undoMiddleware.mdx).
- Need references between entities? Read [References](./references.mdx).
- Prefer learning from a complete example? Open the [Todo List Example](./examples/todoList/todoList.mdx).
---
# mstComparison
This library is very much like `mobx-state-tree` and takes lots of ideas from it, so the transition
should be fairly simple. There are some trade-offs though, as shown in the following chart:
| Feature | `mobx-keystone` | `mobx-state-tree` |
| ----------------------------------------- | --------------------------------------------- | --------------------------- |
| Tree-like structure | | |
| Immutable snapshot generation | | |
| Patch generation | | |
| Action serialization / replaying | | |
| Action middleware support | (1) | |
| - Atomic/Transaction middleware | | |
| - Undo manager middleware | | |
| Flow action support | | |
| References | | |
| Frozen data | | |
| TypeScript support | (2) | |
| Simplified instance / snapshot type usage | | |
| Simplified model life-cycle | | |
| Runtime type validation | (3) | |
| No metadata inside snapshots | (4) | |
| Redux compatibility layer | | |
1. Includes an improved action tracking middleware that makes it easier to create
middlewares for flow (async) actions.
2. Support for self-model references / cross-model references / no need for late types, no need for casting,
etc.
3. Runtime type checking / type definitions are completely optional in `mobx-keystone`.
4. Only when using data models, although they lack life-cycle support.
## TypeScript improvements
`mobx-state-tree` has some limitations when it comes to TypeScript typings, which `mobx-keystone` tries to overcome.
### If you know TypeScript you already know how to type models
When not using runtime type checking, `mobx-keystone` uses standard TypeScript type annotations to declare model data, which lowers the learning curve.
However, if you need runtime type checking, `mobx-keystone` includes a completely optional type definition / runtime type checking system as well.
### Self-recursive and cross-referenced models
Self-recursive or cross-referenced models are impossible (or at least very hard) to properly type in `mobx-state-tree`, but they become trivial with `mobx-keystone`.
```ts
// self recursive model
@model("myApp/TreeNode")
class TreeNode extends Model({ children: prop