skip to content

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?

level: seniorimportance: should knowfreq 28%

answer

  1. 0.85 moved the preset out
  2. 0.87 requires the separate package
  3. old react-native/jest/* paths gone
  4. setupFiles add to the preset's
  5. Node 22.13 or newer

basics

~10 s

React 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 s

In 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
javascript
// 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

for a junior

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.

for a middle

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.

for a senior

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.

for a principal

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