---
title: Migrating from MobX 4/5
sidebar_label: Migrating from MobX 4/5 {🚀}
hide_title: true
---

<script async type="text/javascript" src="//cdn.carbonads.com/carbon.js?serve=CEBD4KQ7&placement=mobxjsorg" id="_carbonads_js"></script>

# Migrating from MobX 4/5 {🚀}

MobX 6 is quite different from MobX 5. This pages covers a migration guide from MobX 4 and 5 to 6, and an extensive list of all the changes.

For a better understanding, check out the MobX 6.0 [CHANGELOG](https://github.com/mobxjs/mobx/blob/main/packages/mobx/CHANGELOG.md#600).

_⚠️ **Warning**: Depending on factors like the size and complexity of your code base, your MobX usage patterns, and the quality of your automated tests, this migration guide might take you anywhere between an hour and a couple of days. Please refrain from upgrading if you don't trust your Continuous Integration or QA / test procedures enough to pick up any unexpected breakages. Unexpected behavioral changes might be caused by changes in MobX itself or the changes needed to your Babel / TypeScript build configuration. ⚠️_

## Getting started

1. Update `mobx` to the latest version of MobX 4/5 and solve any deprecation messages.
2. Update `mobx` to version 6.
3. If you are upgrading from MobX 4, and you will need to support Internet Explorer / React Native without proxies, call `import { configure } from "mobx"; configure({ useProxies: "never" })` at the initialization of your application, to back-out of the Proxy implementation. Check out the [Proxy Support](configuration.md#proxy-support) section for more details.
4. For babel users:
    - If you are using Babel and have class-properties enabled, disable the legacy loose field support: `["@babel/plugin-proposal-class-properties", { "loose": false }]`
    - (Optional) In MobX 6 decorators have become opt-in. If you no longer wish to use decorators, remove `plugin-proposal-decorators` from your babel configuration and dependencies. Check out the [Enabling decorators {🚀}](enabling-decorators.md) section for more details.
5. For Typescript users:
    - Add the flag `"useDefineForClassFields": true` to your compiler config.
    - (Optional) In MobX 6 decorators have become opt-in. If you no longer wish to use decorators, remove / disable the `experimentalDecorators` configuration from your TypeScript config. Check out the [Enabling decorators {🚀}](enabling-decorators.md) section for more details.
6. The MobX default configuration has become more strict. We recommend to adopt the new defaults after completing the upgrade, check out the [Configuration {🚀}](configuration.md) section. During migration, we recommend to configure MobX in the same way as it would be in v4/v5 out of the box: `import {configure} from "mobx"; configure({ enforceActions: "never" });`. After finishing the entire migration process and validating that your project works as expected, consider enabling the flags `computedRequiresReaction`, `reactionRequiresObservable` and `observableRequiresReaction` and `enforceActions: "observed"` to write more idiomatic MobX code.

## Upgrading classes to use `makeObservable`

Due to standardized JavaScript limitations in how class fields are constructed, it is no longer possible for MobX to alter the behavior of class fields by means of decorators or the `decorate` utility. Instead, fields have to be made observable by the `constructor`. This can be done in three different ways:

1. Remove all decorators and call `makeObservable` in the `constructor` and explicitly define which field should be made observable using which decorator. For example: `makeObservable(this, { count: observable, tick: action, elapsedTime: computed })` (note that the second argument corresponds to what would be passed to `decorate`). This is the recommended approach if you want to drop decorators in your code base, and the project isn't yet too big.
2. Leave all the decorators and call `makeObservable(this)` in the `constructor`. This will pick up the metadata generated by the decorators. This is the recommended way if you want to limit the impact of a MobX 6 migration.
3. Remove decorators and use `makeAutoObservable(this)` in the class `constructor`'s.

Check out [makeObservable / makeAutoObservable](observable-state.md) for more details.

Some specifics to note:

1. Using `makeObservable` / `makeAutoObservable` needs to be done in every class definition that declares MobX based members. So if a sub-class and super-class both introduce observable members, they will both have to call `makeObservable`.
2. `makeAutoObservable` will mark methods using a new decorator [`autoAction`](observable-state.md#autoAction), that will apply `action` only if it is not in a derivation context. This makes it safe to call automatically decorated methods also from computed properties.

Migrating a large code base with lots of classes might be daunting. But no worries, there is a code-mod available that will automate the above process!!

## Upgrading your code with the `mobx-undecorate` codemod

If you are an existing MobX user you have code that uses a lot of decorators, or the equivalent calls to `decorate`.

The [`mobx-undecorate`](https://www.npmjs.com/package/mobx-undecorate) package provides a codemod that can automatically update your code to be conformant to MobX 6. There is no need to install it; instead you download and execute it using the [`npx`](https://www.npmjs.com/package/npx) tool which you do need to install if you haven't already.

To get rid of all uses of MobX decorators and replace them with the equivalent `makeObservable` calls, go to the directory that contains your source code and run:

```shell
npx mobx-undecorate
```

MobX will continue to support decorators -- so if you want to retain them
and only introduce `makeObservable(this)` where required, you can use the `--keepDecorators` option:

```shell
npx mobx-undecorate --keepDecorators
```

See [documentation](https://www.npmjs.com/package/mobx-undecorate) for more options.

### Limitations of `mobx-undecorate`

The `mobx-undecorate` command has to introduce a constructor in classes that do not yet have one. If base class of the constructor expects arguments, the codemod cannot introduce these arguments for the subclass being upgraded, and the `super` call won't pass them either. You have to fix these manually.
The tool will generate a `// TODO: [mobx-undecorate]` comment in these cases.

We do have a special case for React class components to do the right thing and
pass along `props` to the superclass.

## Functions are auto-converted

Functions that become part of a deep observable structure are automatically converted to [`autoAction`](observable-state.md#autoAction) or to [`flow`](actions.html#using-flow-instead-of-async--await-) if it's a generator function. See [inference rules](observable-state.html#makeautoobservable) for details.
This means that the original function reference is not preserved - in the same spirit as the original array/object/set/map reference is lost when converted to observable. [This can be surprising in some situations](https://github.com/mobxjs/mobx/issues/3616).
If this behavior is not desired use [`observable.shallow`](observable-state.html#available-annotations) / [`observable.ref`](observable-state.html#available-annotations) / [`false`](observable-state.html#available-annotations) / [`deep: flase`](observable-state.html#options-) to prevent the conversion process or make sure the function is already an `action` as shown in the issue.