From 77d0d84d96e94f3d414518c5e8f6ec3c9156827c Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Thu, 9 Jul 2026 11:50:45 +0200 Subject: [PATCH] Keep react-native/setup-env reachable in the module graph #57475 pointed Metro's getModulesRunBeforeMainModule at 'react-native/setup-env' (src/setup-env.js) instead of InitializeCore. Metro only runs modules from that list that are already part of the bundle graph (getAppendScripts: modules.some(m => m.path === path)), and nothing imports src/setup-env.js at runtime, so it was silently dropped. The RN environment (HMRClient, timers, batched bridge, AppRegistry setup...) then no longer ran before the app's main module, producing a launch-time redbox: Failed to call into JavaScript module method HMRClient.setup(). Module has not been registered as callable. This broke the template E2E tests (blank screen, 'Welcome to React Native' never visible) on both iOS and Android. Fix: have the deprecated InitializeCore delegate to 'react-native/setup-env' via a side-effectful require. InitializeCore is a guaranteed graph entry (via ReactNativePrivateInitializeCore), so this pulls src/setup-env.js into the graph and getModulesRunBeforeMainModule runs it before main again. Behavior is unchanged (both ultimately call setUpDefaultReactNativeEnvironment, which is idempotent). --- packages/react-native/Libraries/Core/InitializeCore.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/react-native/Libraries/Core/InitializeCore.js b/packages/react-native/Libraries/Core/InitializeCore.js index 8846ce4dea5..a53aedfe899 100644 --- a/packages/react-native/Libraries/Core/InitializeCore.js +++ b/packages/react-native/Libraries/Core/InitializeCore.js @@ -27,4 +27,11 @@ 'use strict'; -require('../../src/private/setup/setUpDefaultReactNativeEnvironment').default(); +// NOTE: This delegates to the `'react-native/setup-env'` entry point (rather +// than calling `setUpDefaultReactNativeEnvironment` directly) so that +// `src/setup-env.js` is pulled into the module graph. Metro's +// `getModulesRunBeforeMainModule` only runs modules that are already part of +// the bundle, and `InitializeCore` is a guaranteed graph entry (via +// `ReactNativePrivateInitializeCore`). This keeps `'react-native/setup-env'` +// reachable so it runs before the main module. +require('../../src/setup-env');