After upgrading a React Native app from 0.84 to 0.87, Jest cannot find the react-native preset; what changed, and what else must you recheck in the config?
answer
- 0.85 moved the preset out
- 0.87 requires the separate package
- old react-native/jest/* paths gone
- setupFiles add to the preset's
- Node 22.13 or newer
basics
~10 sReact Native 0.85 moved the Jest preset into @react-native/jest-preset and 0.87 requires consuming it from there. Install it at the matching version, change preset, and fix custom config that still points at react-native/jest paths.
solid answer
~40 sIn 0.85 the preset was extracted from `react-native` into `@react-native/jest-preset`, and the 0.87 notes say it must now be consumed as that package; the `react-native` package no longer carries a Jest preset, so `preset: 'react-native'` fails. Install `@react-native/jest-preset` at the same version as `react-native` and set `preset: '@react-native/jest-preset'`. Then recheck everything custom: `setupFiles` or transformers that referenced files under `react-native/jest/`, a hand-written `transformIgnorePatterns` that must still include the React Native entries, library setup files that must stay in `setupFiles`, deep `react-native/Libraries/...` paths in mocks, and the Node version, since 0.87 requires Node 22.13 or newer. Run the whole suite before trusting it.
code
javascript · 8 lines// jest.config.js after the upgrade
module.exports = {
preset: '@react-native/jest-preset',
setupFiles: ['react-native-gesture-handler/jestSetup.js'],
transformIgnorePatterns: [
'node_modules/(?!((jest-)?react-native|@react-native(-community)?|react-native-gesture-handler)/)',
],
};go deeper
Recall that the Jest preset moved to @react-native/jest-preset in 0.85 and that 0.87 requires the new package name in jest.config.js.
Explain which custom config entries depend on the old location and how the preset's setupFiles and transformIgnorePatterns interact with a project's own values.
Run the upgrade as a checklist: stale react-native/jest paths, transform allowlist, library setup files, deep-import mocks and the Node 22.13 floor, then verify from a clean install.
Keep test configuration inside the upgrade's definition of done, and budget for it when setting a React Native upgrade cadence across teams.
## What changed between 0.84 and 0.87 Up to React Native 0.84, the Jest preset lived inside the `react-native` package, and a project's Jest config said `preset: 'react-native'`. Two releases changed that: - **0.85** extracted the preset into its own package, **`@react-native/jest-preset`**, and the release post described the migration as a one-line change of the `preset` value. - **0.87** listed, under packages and tooling, that `@react-native/jest-preset` **must now be consumed as a package**. The 0.87 `react-native` package contains no Jest preset, so the old value no longer resolves. The new package is versioned in lockstep with React Native (0.87.1 alongside `[email protected]`) and declares `babel-jest`, `jest-environment-node` and `@react-native/js-polyfills` as its own dependencies. ## The upgrade checklist 1. **Install and point at the new package.** Add `@react-native/jest-preset` as a dev dependency at the React Native version and set `preset: '@react-native/jest-preset'`. 2. **Hunt old internal paths.** Before the move, the preset's files lived under `react-native/jest/` (the new asset transformer even carries a comment saying it used to be at `react-native/jest/assetFileTransformer.js`). Any custom `setupFiles`, `transform` or `moduleNameMapper` entry that points at `react-native/jest/...` breaks; remove it or point at the preset package. 3. **Recheck `transformIgnorePatterns`.** A project that overrides it replaces the preset's pattern, so the override must still contain the React Native entries, `(jest-)?react-native|@react-native(-community)?`, next to its own untranspiled packages. 4. **Recheck `setupFiles`.** Jest adds a project's `setupFiles` after the preset's, so library setup scripts (for example a gesture library's `jestSetup.js`) stay in the project config and still run after React Native's setup. 5. **Recheck deep imports used in mocks.** 0.87 makes the Strict TypeScript API the default, where deep `react-native/Libraries/...` imports are a type error in app code. The preset's resolver still lets Jest resolve and mock those internal paths, but they are internal: prefer mocking public modules, and expect renames such as `Libraries/Core/InitializeCore`, deprecated in favour of `react-native/setup-env`. 6. **Recheck the toolchain.** React Native 0.87 requires Node.js 22.13 or newer, and the preset package's `engines` field says the same, so an old Node on a CI image fails the run. 7. **Run the whole suite and read the first failure.** Parse errors point at transforms, crashes in native calls point at mocks, and missing module errors point at stale paths. ## A before-and-after config | Setting | 0.84 project | 0.87 project | |---|---|---| | `preset` | `'react-native'` | `'@react-native/jest-preset'` | | Preset installed as | part of `react-native` | its own dev dependency, same version | | Custom asset transformer path | `react-native/jest/assetFileTransformer.js` | not needed; the preset supplies it | | `transformIgnorePatterns` override | must list React Native entries | unchanged rule, recheck after edits | | Minimum Node | older LTS lines | 22.13 | ## Why this is a senior question The rename itself is trivial. The judgment is in treating the test configuration as part of the upgrade rather than an afterthought: - **Upgrade guides list the change once**; the breakage appears in several places that grew around the old paths over years. - **A partially fixed config can pass** while silently skipping something: for example, an override of `transformIgnorePatterns` that forgot the React Native entries fails loudly, but a stale mock path can leave a real module unmocked in some suites and not others. - **Expo projects follow the SDK.** Expo apps use the `jest-expo` preset, and Expo SDK 57 runs React Native 0.86. Upgrading the SDK means upgrading `jest-expo` with it, which `npx expo install` does by picking the version that matches the SDK. ## How to verify you are done - The suite passes from a clean install with no cached transforms. - `git grep` finds no `react-native/jest/` references in config or setup files. - CI runs on a Node version that satisfies React Native's `engines` field. - A deliberately broken import of an untranspiled dependency still fails, proving `transformIgnorePatterns` is doing its job rather than being bypassed.
- After switching the preset name, a custom transform entry for images still fails with a module-not-found error; why?The asset transformer used to live at `react-native/jest/assetFileTransformer.js`, and projects sometimes referenced it by that path. The file now ships inside `@react-native/jest-preset`, which already maps image extensions to it, so the custom entry can simply be removed.
- Why can CI fail after the upgrade even though Jest passes on the developer's machine?React Native 0.87 requires Node.js 22.13 or newer. A CI image pinned to an older Node line can fail installing or running the toolchain while a developer's newer local Node works, so the CI Node version belongs on the upgrade checklist.
saying these in an interview costs you the question
- The preset move is cosmetic, so only the preset line needs changing
- The react-native package in 0.87 still ships a jest-preset fallback
- A custom setupFiles list replaces the preset's own setup file
- Paths under react-native/jest/ remain valid after the move
- The Jest preset is versioned independently of React Native