{"id":17820,"library":"mst-middlewares","title":"MobX-State-Tree Prebuilt Middlewares","description":"mst-middlewares provides a collection of prebuilt middlewares for MobX-State-Tree (MST), primarily serving as examples and starting points for developers to create their own custom MST middlewares. Originally part of the `mobx-state-tree` monorepo, it was extracted into its own package to keep the core MST library small. The package is currently at version 6.1.0 and appears to have a release cadence driven by contributions and fixes, with a recent major bump to v6.0.0. Key differentiators include its direct lineage from the official MST repository, offering basic but functional examples like action logging and transactional rollbacks, and encouraging direct modification or copy-pasting of its source for specific project needs rather than relying on them as fully-fledged, heavily-supported features. Developers are encouraged to read the source code to understand how to implement custom middleware for MST's event system.","status":"active","version":"6.1.0","language":"javascript","source_language":"en","source_url":"https://github.com/coolsoftwaretyler/mst-middlewares","tags":["javascript","typescript"],"install":[{"cmd":"npm install mst-middlewares","lang":"bash","label":"npm"},{"cmd":"yarn add mst-middlewares","lang":"bash","label":"yarn"},{"cmd":"pnpm add mst-middlewares","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Core dependency for MST middleware functionality, required for `addMiddleware` and `decorate`.","package":"mobx-state-tree","optional":false}],"imports":[{"note":"Primarily designed for ESM usage. While CommonJS `require` might work with transpilation, direct ESM import is idiomatic for modern Node.js and bundlers.","wrong":"const simpleActionLogger = require('mst-middlewares').simpleActionLogger;","symbol":"simpleActionLogger","correct":"import { simpleActionLogger } from 'mst-middlewares';"},{"note":"All provided middlewares are named exports from the main package entry point.","wrong":"import actionLogger from 'mst-middlewares/actionLogger';","symbol":"actionLogger","correct":"import { actionLogger } from 'mst-middlewares';"},{"note":"The `atomic` middleware is a named export. Incorrectly importing the entire module as default will not yield the expected middleware function.","wrong":"const atomic = require('mst-middlewares');","symbol":"atomic","correct":"import { atomic } from 'mst-middlewares';"}],"quickstart":{"code":"import { types, addMiddleware, flow } from 'mobx-state-tree';\nimport { atomic } from 'mst-middlewares';\n\nconst delay = (ms: number) => new Promise(res => setTimeout(res, ms));\n\nconst TestModel = types\n  .model({\n    z: types.number,\n  })\n  .actions((self) => {\n    // Example of adding middleware directly\n    addMiddleware(self, atomic);\n\n    return {\n      inc: flow(function* (x: number) {\n        console.log(`Initial z: ${self.z}`);\n        yield delay(2);\n        self.z += x;\n        console.log(`z after first increment: ${self.z}`);\n        yield delay(2);\n        self.z += x;\n        console.log(`z after second increment: ${self.z}`);\n        throw new Error(\"Oops, something went wrong!\");\n      }),\n    };\n  });\n\nconst m = TestModel.create({ z: 1 });\n\nm.inc(3).catch((error: Error) => {\n  console.error(`Caught error: ${error.message}`);\n  console.log(`z after failed action (should be rolled back): ${m.z}`); // Expected: 1\n});\n","lang":"typescript","description":"This quickstart demonstrates the `atomic` middleware, which ensures that any modifications made within a synchronous or asynchronous action are rolled back if the action fails. It shows how to use `addMiddleware` on a model instance and verifies that the state (`m.z`) returns to its initial value after a `flow` action throws an error."},"warnings":[{"fix":"Review any custom middleware that inspects the type of state returned by `recorder.undo()`. Adjust logic to account for this change, as the undo operation will no longer be seen as an `UndoState`.","message":"Version 6.0.0 included a fix where `recorder.undo()` actions no longer register as an `UndoState` in the middleware. This might affect custom middleware logic that relies on inspecting the type of state produced by `recorder.undo()` operations.","severity":"breaking","affected_versions":">=6.0.0"},{"fix":"For critical systems, it is strongly recommended to copy and paste the source code of the desired middleware and tailor it to specific needs, rather than relying solely on the package's default implementations. This allows for full control and custom error handling/feature additions.","message":"The provided middlewares are explicitly described as examples and are supported on a 'best effort' basis. They are not intended as fully robust, production-ready solutions for all use cases.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Always review the source code of any middleware you plan to use in production to understand its limitations and potential areas for improvement or customization for your specific application.","message":"The package originated from an undo of the MobX-State-Tree monorepo setup. This implies a historical context where these middlewares were internal examples, and their design reflects that, prioritizing clarity and demonstration over extreme optimization or comprehensive feature sets.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-23T00:00:00.000Z","next_check":"2026-07-22T00:00:00.000Z","problems":[{"fix":"Ensure `mobx-state-tree` is installed (`npm install mobx-state-tree` or `yarn add mobx-state-tree`) and that `addMiddleware` or `decorate` are being called on a valid MST model instance created with `types.model.create()`.","cause":"Attempting to use `addMiddleware` or `decorate` without `mobx-state-tree` being correctly installed as a peer dependency, or trying to apply middleware to an object that isn't a valid MST instance.","error":"TypeError: Cannot read properties of undefined (reading 'addMiddleware')"},{"fix":"For CommonJS projects, either configure your project to use ESM (e.g., set `\"type\": \"module\"` in `package.json` and adjust file extensions to `.js` or `.mjs`) or use a transpiler like Babel or TypeScript to convert ESM imports to CJS `require` statements during build. Modern Node.js versions support ESM directly when `\"type\": \"module\"` is set.","cause":"Attempting to use `import` syntax in a CommonJS (CJS) environment without proper transpilation or configuration (e.g., in an older Node.js project without `\"type\": \"module\"` in `package.json`).","error":"SyntaxError: Cannot use import statement outside a module"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}