|
| 1 | +--- |
| 2 | +title: Split Jest from React Native Core |
| 3 | +author: |
| 4 | +- Phil Pluckthun |
| 5 | +- Cedric van Putten |
| 6 | +date: 2025-08-17 |
| 7 | +--- |
| 8 | + |
| 9 | +# RFC0000: Split Jest from React Native Core |
| 10 | + |
| 11 | +## Summary |
| 12 | + |
| 13 | +This RFC proposes the removal of `react-native/jest-preset` from the core React Native package, and moving it to `@react-native/jest-preset` instead, making Jest an optional testing framework that developers can choose to integrate only if desired. This change would acknowledge the ongoing changes in test runner preferences and ease maintenance. |
| 14 | + |
| 15 | +## Basic example |
| 16 | + |
| 17 | +Currently, `react-native` itself contains a Jest preset and after setting up a project is available at `react-native/jest-preset`. |
| 18 | + |
| 19 | +```json |
| 20 | +{ |
| 21 | + "dependencies": { |
| 22 | + "react-native": "0.81.x" |
| 23 | + }, |
| 24 | + "devDependencies": { |
| 25 | + "jest": "*" |
| 26 | + } |
| 27 | +} |
| 28 | +``` |
| 29 | + |
| 30 | +The proposed change is to split this out into a separate, `@react-native/jest-preset` package, thus; |
| 31 | + |
| 32 | +```json |
| 33 | +{ |
| 34 | + "dependencies": { |
| 35 | + "react-native": "0.81.x" |
| 36 | + }, |
| 37 | + "devDependencies": { |
| 38 | + "@react-native/jest-preset": "0.81.x", |
| 39 | + "jest": "*" |
| 40 | + } |
| 41 | +} |
| 42 | +``` |
| 43 | + |
| 44 | +## Motivation |
| 45 | + |
| 46 | +There are several key motivations for this change: |
| 47 | + |
| 48 | +- **Maintenance Status:** While Jest 30 has now been released after a long break of major maintenance updates, the [Jest 30 includes a regression for `transformIgnorePatterns`](https://github.com/jestjs/jest/issues/15781), demonstrating that React Native isn't Jest's main focus, and that continuously maintaining a Jest preset in React Native that is part of the core package poses challenges. |
| 49 | +- **Ecosystem Evolution:** Outside of Meta, many teams and projects have migrated to alternative testing solutions, especially for unit testing, such as Vitest. These days alternative test runners exist that are better set up to support React Native in the future, that the ecosystem signals they're starting to prefer. By bundling the Jest preset by default, we create an artificial constraint and recommendation that doesn't reflect current practices. |
| 50 | +- **Dependency Management and size:** Including Jest by default adds significant weight to `node_modules` and projects' dependency graphs, even for projects that may be using alternative testing frameworks or no testing framework at all. |
| 51 | +- **Testing Strategy Flexibility:** Different projects have different testing needs and requirements. Apart from unit testing, many projects implement integration or E2E tests, such as with Cypress and Maestro. This ultimately means that Jest is only fulfilling one requirement with alternatives being available. |
| 52 | +- **Reduced Maintenance Burden:** By making Jest optional, the React Native core team can focus on the maintenance of React Native itself and signals that maintenance of the Jest preset isn't coupled to React Native releases necessarily. This is in line with the Learn Core initiative. |
| 53 | + |
| 54 | +In short, this change affirms Jest being a choice and comes with maintenance and installation speed benefits. |
| 55 | + |
| 56 | +## Detailed design |
| 57 | + |
| 58 | +1. Create a separate package, `@react-native/jest-preset` |
| 59 | +2. The current `jest` sub-folder and `jest-preset.js` move to the new package |
| 60 | +3. `@jest/create-cache-key-function`, `babel-jest`, `jest-environment-node`, `babel-plugin-syntax-hermes-parser` |
| 61 | +4. Update template projects, as appropriate to switch from `react-native/jest-preset` to `@react-native/jest-preset` |
| 62 | +5. Update documentation, as needed to switch from `react-native/jest-preset` to `@react-native/jest-preset` |
| 63 | + |
| 64 | +**Note:** There's an implicit usage of `react-test-renderer` in the `react-native/jest` folder. This package is deprecated, and moving this out of `react-native` also removes the deprecated testing recommendation from `react-native`. |
| 65 | + |
| 66 | +### Migration Path |
| 67 | + |
| 68 | +- Install `@react-native/jest-preset` as a dev-dependency |
| 69 | +- Switch `preset` in your Jest configuration to `@react-native/jest-preset` |
| 70 | + |
| 71 | +## Drawbacks |
| 72 | + |
| 73 | +- **Migration**: Existing projects will need to add the new dependency |
| 74 | +- **Documentation:** If any documentation assumed Jest, it will now need to point at new instructions or clarify that Jest is optional. |
| 75 | +- **Fragmentation:** While Jest may not be the best choice for every project, this removes a default choice, which may mean beginners are faced with an additional decision. |
| 76 | +- **Template**: Templates will have to choose whether or not to include Jest and the preset. |
| 77 | + |
| 78 | +## Alternatives |
| 79 | + |
| 80 | +- **Continue including Jest:** We could continue including the preset, and take on the maintenance burden associated with this, as long as development and support is revilatised. |
| 81 | +- **Switch default testing framework:** We could replace Jest with another test framework and runner like Vitest. However, this increases maintenance burden. |
| 82 | +- **Minimal testing interface:** We could create a framework-agnostic unit testing interface. However, `@testing-library/react-native` already exists. |
| 83 | + |
| 84 | +This proposal was chosen partially because options for E2E testing already exist, and alternative runners can use `@testing-library/react-native`. The main complexity of replacing Jest for React Native is associated with bundling. However, as new projects make strides in supporting more projects, as long as native-platform-extension support and Babel preset transpilation of all modules is possible, a test framework can start supporting React Native. Removing the `jest-preset` from `react-native` signals to contributors to encourage other test runners to support React Native, and encourages external maintenance of new test runners. |
| 85 | + |
| 86 | +## Adoption strategy |
| 87 | + |
| 88 | +1. Publish `@react-native/jest-preset` in parallel to an ongoing stable release. |
| 89 | +2. Pick a warning into `react-native/jest-preset` that informs users of the package change. |
| 90 | +3. Drop `react-native/jest-preset` in a subsequent release. |
| 91 | + |
| 92 | +The change to projects is an added dependency and a single line of changing the Jest preset. No codemod will be needed. |
| 93 | + |
| 94 | +Coordination may be needed with maintainers of templates that currently set up Jest. |
| 95 | + |
| 96 | +## How we teach this |
| 97 | + |
| 98 | +- Documentation should reference `@react-native/jest-preset` when appropriate, but can continue referring to "the React Native Jest preset" |
| 99 | +- Documentation should add instructions to install `@react-native/jest-preset`, where previously it may have left out instructions |
| 100 | +- When referring to React Native testing, no assumption should be made on which testing methodology or framework developers may choose to use |
| 101 | + |
| 102 | +## Unresolved questions |
| 103 | + |
| 104 | +- Templates: Should templates include Jest generally, or not? |
| 105 | +- Community: Will more test runners be encouraged to provide React Native support by this change? |
| 106 | +- Documentation: Should any React Native documentation mention other testing frameworks and actively add new testing frameworks? |
0 commit comments