Skip to content

chore: upgrade React Native from 0.72.15 to 0.76.9 with babel configuration updates#844

Draft
georgewrmarshall wants to merge 9 commits intomainfrom
upgrade-react-native
Draft

chore: upgrade React Native from 0.72.15 to 0.76.9 with babel configuration updates#844
georgewrmarshall wants to merge 9 commits intomainfrom
upgrade-react-native

Conversation

@georgewrmarshall
Copy link
Contributor

@georgewrmarshall georgewrmarshall commented Oct 21, 2025

Description

Upgrades React Native from 0.72.15 to 0.76.9 and updates associated build configurations to ensure compatibility with the latest React Native version. This includes modernizing Babel configurations, updating Jest test setup, reorganizing font assets, and upgrading related dependencies for improved performance and future-proofing.

Key changes include replacing deprecated metro-react-native-babel-preset with the new @react-native/babel-preset, updating Jest transform patterns to properly handle React Native 0.76.9 modules, and organizing Storybook font assets into a proper assets/fonts directory structure.

Related issues

Fixes:

Manual testing steps

  1. Install dependencies: yarn install
  2. Build the React Native design system package: yarn workspace @metamask/design-system-react-native build
  3. Run tests to verify compatibility: yarn workspace @metamask/design-system-react-native test
  4. Start Storybook React Native app: yarn storybook:ios or yarn storybook:android
  5. Verify that components render correctly and fonts load properly
  6. Test component interactions and animations with React Native Reanimated 3.17.2
  7. Verify Jest tests pass with the updated configuration

Screenshots/Recordings

Before

After

Pre-merge author checklist

  • I've followed MetaMask Contributor Docs
  • I've completed the PR template to the best of my ability
  • I've included tests if applicable
  • I've documented my code using JSDoc format if applicable
  • I've applied the right labels on the PR (see labeling guidelines). Not required for external contributors.

Pre-merge reviewer checklist

  • I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed).
  • I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.

Note

High Risk
Upgrades core runtime/tooling versions (React Native, Expo, Reanimated, React) and adjusts Metro/Babel/Jest configuration, which can cause widespread build/test/runtime regressions across packages and Storybook.

Overview
Upgrades the monorepo’s React/React Native stack to react@18.3.1 and react-native@0.76.9, including the Expo Storybook app moving to expo@52 and updating related deps (Reanimated, gesture-handler, testing-library, etc.).

Modernizes RN build/test tooling by switching the RN package test Babel preset to @react-native/babel-preset, updating Jest transforms/ignores and adding module mappers for RN 0.76 internals, and revising the Storybook RN Metro config for monorepo resolution and SVG support.

Refactors Storybook React Native setup by moving theming decorators from config.js to preview.js, updating Expo root registration, expanding story globs to include previously excluded temp-components, and configuring font loading via expo-font plugin in app.json (plus ignoring generated ios/ and android/ app folders).

Written by Cursor Bugbot for commit ad39389. This will update automatically on new commits. Configure here.

@socket-security
Copy link

socket-security bot commented Oct 21, 2025

All alerts resolved. Learn more about Socket for GitHub.

This PR previously contained dependency changes with security issues that have been resolved, removed, or ignored.

Ignoring alerts on:

  • babel-plugin-syntax-hermes-parser@0.23.1
  • babel-plugin-syntax-hermes-parser@0.25.1
  • @react-native/community-cli-plugin@0.76.9
  • expo-splash-screen@31.0.10
  • @react-native/babel-preset@0.76.9
  • @react-native/typescript-config@0.76.9
  • @react-native/dev-middleware@0.76.9
  • @react-native/metro-babel-transformer@0.76.9
  • @babel/traverse--for-generate-function-map@7.28.4
  • @expo/fingerprint@0.11.11
  • web-streams-polyfill@3.3.3
  • whatwg-url-without-unicode@8.0.0-3
  • resolve-workspace-root@2.0.0
  • resolve-global@1.0.0
  • react-native-is-edge-to-edge@1.1.7
  • @react-native/babel-plugin-codegen@0.76.9
  • @jest/get-type@30.1.0
  • @jest/diff-sequences@30.0.1
  • @isaacs/ttlcache@1.4.1
  • @react-native/debugger-frontend@0.76.9
  • chrome-launcher@0.15.2
  • chromium-edge-launcher@0.2.0
  • selfsigned@2.4.1
  • @expo/ws-tunnel@1.0.6
  • global-dirs@0.1.1
  • lighthouse-logger@1.4.2
  • @types/node-forge@1.3.14
  • @expo/sudo-prompt@9.3.2
  • lightningcss-freebsd-x64@1.27.0
  • lightningcss-win32-arm64-msvc@1.27.0
  • marky@1.3.0
  • picomatch@3.0.1
  • jest-matcher-utils@30.2.0
  • jest-diff@30.2.0
  • undici@6.22.0
  • react-refresh@0.14.2
  • webidl-conversions@5.0.0
  • @jest/schemas@30.0.5
  • babel-plugin-polyfill-corejs3@0.13.0
  • @sinclair/typebox@0.34.41
  • getenv@2.0.0
  • hermes-parser@0.25.1
  • hermes-parser@0.23.1
  • hermes-estree@0.25.1
  • hermes-estree@0.23.1
  • bplist-creator@0.0.7
  • pretty-format@30.2.0
  • commander@12.1.0
  • @expo/json-file@9.1.5
  • @expo/json-file@9.0.2
  • @expo/json-file@10.0.7
  • open@7.4.2
  • @babel/plugin-transform-modules-commonjs@7.27.1
  • @babel/preset-typescript@7.27.1
  • react-native@0.76.9
  • react-native-gesture-handler@2.16.2
  • react-native-reanimated@3.19.3
  • @babel/plugin-syntax-jsx@7.27.1
  • @babel/plugin-transform-typescript@7.28.0
  • dotenv@16.4.7
  • @react-native/assets-registry@0.76.9
  • @react-native/codegen@0.76.9
  • @react-native/gradle-plugin@0.76.9
  • @react-native/js-polyfills@0.76.9
  • @react-native/normalize-colors@0.76.9
  • @react-native/normalize-colors@0.81.5
  • @react-native/normalize-colors@0.74.85
  • @react-native/virtualized-lists@0.76.9
  • flow-enums-runtime@0.0.6
  • metro-runtime@0.81.5
  • metro-source-map@0.81.5
  • react-devtools-core@5.3.2
  • @babel/runtime@7.28.4
  • expo@52.0.47
  • expo-status-bar@2.0.1
  • expo-system-ui@3.0.7
  • @babel/preset-react@7.27.1
  • @testing-library/react-native@13.3.3
  • browserslist@4.26.3
  • metro-symbolicate@0.81.5
  • ob1@0.81.5
  • @expo/cli@0.22.26
  • @expo/osascript@2.3.7
  • @expo/config@12.0.10
  • @expo/config@10.0.11
  • @expo/config-plugins@54.0.2
  • @expo/config-plugins@9.0.17
  • @expo/vector-icons@14.0.4
  • babel-preset-expo@12.0.11
  • expo-asset@11.0.5
  • expo-constants@17.0.8
  • expo-file-system@18.0.12
  • expo-font@14.0.9
  • expo-font@13.0.4
  • expo-keep-awake@14.0.3
  • expo-modules-autolinking@2.0.8
  • expo-modules-core@2.2.3
  • @babel/plugin-transform-async-generator-functions@7.28.0
  • @babel/plugin-transform-async-to-generator@7.27.1
  • @babel/plugin-transform-block-scoping@7.28.4
  • @babel/plugin-transform-classes@7.28.4
  • @babel/plugin-transform-computed-properties@7.27.1
  • @babel/plugin-transform-destructuring@7.28.0
  • @babel/plugin-transform-export-namespace-from@7.27.1
  • @babel/plugin-transform-logical-assignment-operators@7.27.1
  • @babel/plugin-transform-numeric-separator@7.27.1
  • @babel/plugin-transform-object-rest-spread@7.28.4
  • @babel/plugin-transform-optional-catch-binding@7.27.1
  • @babel/plugin-transform-private-methods@7.27.1
  • @babel/plugin-transform-private-property-in-object@7.27.1
  • @babel/plugin-transform-regenerator@7.28.4
  • @babel/plugin-transform-spread@7.27.1
  • babel-plugin-polyfill-corejs2@0.4.14
  • babel-plugin-polyfill-regenerator@0.6.5
  • core-js-compat@3.46.0
  • @babel/plugin-transform-react-jsx@7.27.1
  • @babel/plugin-transform-react-jsx-development@7.27.1
  • @babel/plugin-transform-react-pure-annotations@7.27.1
  • @babel/plugin-proposal-export-default-from@7.27.1
  • @babel/plugin-syntax-export-default-from@7.27.1
  • @babel/plugin-syntax-flow@7.27.1
  • @babel/plugin-transform-flow-strip-types@7.27.1
  • @babel/plugin-transform-runtime@7.28.3
  • baseline-browser-mapping@2.8.19
  • electron-to-chromium@1.5.237
  • node-releases@2.0.26
  • update-browserslist-db@1.1.3
  • metro@0.81.5
  • metro-config@0.81.5
  • metro-core@0.81.5
  • metro-resolver@0.81.5
  • compression@1.8.1
  • @expo/devcert@1.2.0
  • @expo/env@0.4.2
  • @expo/metro-config@0.19.12
  • @expo/package-manager@1.9.8
  • @expo/plist@0.4.7
  • @expo/plist@0.2.2
  • @expo/prebuild-config@54.0.6
  • @expo/prebuild-config@8.2.0
  • @urql/core@5.2.0
  • @urql/exchange-retry@1.3.2
  • @expo/config-types@54.0.8
  • @expo/config-types@52.0.5
  • babel-plugin-react-native-web@0.19.13
  • dotenv-expand@11.0.7
  • metro-babel-transformer@0.81.5
  • metro-cache@0.81.5
  • metro-cache-key@0.81.5
  • metro-file-map@0.81.5
  • metro-transform-plugins@0.81.5
  • metro-transform-worker@0.81.5
  • on-headers@1.1.0
  • lightningcss@1.27.0
  • @expo/image-utils@0.8.7
  • @expo/image-utils@0.6.5
  • @0no-co/graphql.web@1.2.0
  • metro-minify-terser@0.81.5
  • lightningcss-darwin-arm64@1.27.0
  • lightningcss-darwin-x64@1.27.0
  • lightningcss-linux-arm-gnueabihf@1.27.0
  • lightningcss-linux-arm64-gnu@1.27.0
  • lightningcss-linux-arm64-musl@1.27.0
  • lightningcss-linux-x64-gnu@1.27.0
  • lightningcss-linux-x64-musl@1.27.0
  • lightningcss-win32-x64-msvc@1.27.0

View full report

@github-actions
Copy link
Contributor

📖 Storybook Preview

@github-actions
Copy link
Contributor

github-actions bot commented Nov 7, 2025

📖 Storybook Preview

@github-actions
Copy link
Contributor

📖 Storybook Preview

@georgewrmarshall
Copy link
Contributor Author

@SocketSecurity ignore-all
These dependencies are all related to React Native and Expo, and are expected as part of the upgrade.

Comment on lines -14 to -25

jest.mock('react-native-reanimated', () => {
const Reanimated = require('react-native-reanimated/mock');

// Overriding the `call` method to avoid issues with animations
Reanimated.default.call = () => {};

return Reanimated;
});

// Silence warnings related to the Animated API
jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper');
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

React Native Reanimated mock removed - version 3.17.2 should handle React Native 0.76 compatibility better

@github-actions
Copy link
Contributor

📖 Storybook Preview

color = IconColor.IconDefault,
twClassName,
style,
hitSlop,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Destructured hitSlop prop silently dropped, never forwarded

Medium Severity

The newly added hitSlop destructuring on the Icon component extracts the prop from the rest ...props object, but it's never passed to the rendered SVG component. Since the return statement only spreads {...props}, and hitSlop has been pulled out of that spread, any consumer passing hitSlop to Icon will have it silently ignored. The prop needs to either be forwarded explicitly to SVG or left in the ...props spread by removing the destructuring.

Fix in Cursor Fix in Web

'^react-native/Libraries/vendor/emitter/EventEmitter$':
'<rootDir>/jest.setup.js',
'^react-native/Libraries/EventEmitter/RCTDeviceEventEmitter$':
'<rootDir>/jest.setup.js',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jest.setup.js misused as module mock target

Low Severity

The moduleNameMapper maps internal React Native EventEmitter and RCTDeviceEventEmitter modules to jest.setup.js, which doesn't export any EventEmitter-compatible API — it only contains a jest.mock call for react-native-svg. Any code transitively requiring these modules will receive an empty object {}, and the setup file is now pulling double duty as both a setupFilesAfterEnv entry and a mock module, which is fragile and confusing. A dedicated empty mock file would be more appropriate.

Fix in Cursor Fix in Web

Copy link
Contributor

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

There are 4 total unresolved issues (including 2 from previous reviews).

Fix All in Cursor

Bugbot Autofix prepared fixes for both issues found in the latest run.

  • ✅ Fixed: Duplicate JSX transform from conflicting Babel presets
    • Removed '@babel/preset-react' and set '@react-native/babel-preset' jsxRuntime: 'automatic' to prevent duplicate JSX transforms.
  • ✅ Fixed: Missing reanimated setUpTests() call after removing mock
    • Added require('react-native-reanimated').setUpTests() in jest.setup.js to initialize Reanimated for Jest.

Create PR

Or push these changes by commenting:

@cursor push 884076eb43
Preview (884076eb43)
diff --git a/packages/design-system-react-native/babel.config.js b/packages/design-system-react-native/babel.config.js
--- a/packages/design-system-react-native/babel.config.js
+++ b/packages/design-system-react-native/babel.config.js
@@ -2,11 +2,10 @@
   env: {
     test: {
       presets: [
-        '@react-native/babel-preset',
         [
-          '@babel/preset-react',
+          '@react-native/babel-preset',
           {
-            runtime: 'automatic',
+            jsxRuntime: 'automatic',
           },
         ],
         [

diff --git a/packages/design-system-react-native/jest.setup.js b/packages/design-system-react-native/jest.setup.js
--- a/packages/design-system-react-native/jest.setup.js
+++ b/packages/design-system-react-native/jest.setup.js
@@ -1,3 +1,5 @@
+require('react-native-reanimated').setUpTests();
+
 jest.mock('react-native-svg', () => {
   const React = require('react');
   const { View } = require('react-native');

test: {
presets: [
'module:metro-react-native-babel-preset',
'@babel/preset-env',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate JSX transform from conflicting Babel presets

Medium Severity

Both @react-native/babel-preset (which includes @babel/plugin-transform-react-jsx) and a separate @babel/preset-react with runtime: 'automatic' are listed. This causes duplicate JSX transformation, potentially leading to "Duplicate __self prop found" errors or other conflicts. @react-native/babel-preset supports a jsxRuntime: 'automatic' option directly, making the separate preset unnecessary.

Fix in Cursor Fix in Web

Rect: MockedSvg,
};
});

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing reanimated setUpTests() call after removing mock

High Severity

The old jest.mock('react-native-reanimated', ...) was removed, but the replacement require('react-native-reanimated').setUpTests() required by reanimated 3.17.x was never added. Components like ButtonAnimated use useSharedValue and useAnimatedStyle from reanimated — without the setup call, these functions won't have Jest-compatible implementations and tests will fail.

Fix in Cursor Fix in Web

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant