Skip to content

iOS prebuilt core: React explicit-module build fails after a Debug-to-Release swap #57803

Description

@pawicao

Description

An iOS Release build can fail during PrecompileModule React. Clang reports seven include of non-modular header inside framework module errors for React.* modules. I reproduced this failure with React Native 0.87.0-rc.2 and 0.87.0-rc.3.

React Native downloads separate Debug and Release archives for React-Core-prebuilt. In this setup, CocoaPods uses the Debug archive as the initial pod source. For each Xcode build, the [CP-User] [RNCore] Replace React Native Core for the right configuration, if needed build phase runs the replace-rncore-version.js script.

The script reads Pods/React-Core-prebuilt/.last_build_configuration. If the saved configuration differs from the current configuration, the script replaces the prebuilt files with the files for the current configuration.

In the failing repro, the saved configuration is Debug and the Xcode build configuration is Release. Therefore, replace-rncore-version.js starts a Debug-to-Release replacement.

During this replacement, replace-rncore-version.js removes these directories from Pods:

React-Core-prebuilt/Headers
React-Core-prebuilt/React.xcframework

The script then copies the Release files into the same paths. React Native adds this module-map argument to OTHER_CFLAGS during pod install:

-fmodule-map-file=$(PODS_ROOT)/React-Core-prebuilt/Headers/module.modulemap

The failed Clang command contains other -fmodule-map-file arguments, but it does not contain this argument. Clang reports headers from RCTDeprecation, yoga, and react as non-modular headers. The build fails with seven -Wnon-modular-include-in-framework-module errors.

The control build passes when the stored RNCore configuration is already Release. This control does not start the RNCore replacement. The build also passes with this one build setting:

CLANG_ENABLE_EXPLICIT_MODULES=NO

I ran the same configuration-switch test on Xcode 26.3 with these React Native versions:

React Native Result
0.86.2 Pass
0.87.0-rc.1 Pass
0.87.0-rc.2 Fail with seven errors
0.87.0-rc.3 Fail with seven errors

Steps to reproduce

  1. Clone the public reproducer:

    git clone https://github.com/pawicao/react-native-rncore-swap-repro.git
    cd react-native-rncore-swap-repro
  2. Install the packages:

    cd ReproducerApp
    yarn install --frozen-lockfile
    bundle install
    cd ios
    bundle exec pod install
    cd ../..
  3. Run the repro once:

    bash repro-rncore-swap.sh

The script writes Debug to Pods/React-Core-prebuilt/.last_build_configuration. It then starts a Release build with new DerivedData.

The build fails in PrecompileModule React.

Run the control test:

RNCORE_PREVIOUS_CONFIGURATION=Release bash repro-rncore-swap.sh

The control build passes.

Run the workaround test:

bash repro-rncore-swap.sh CLANG_ENABLE_EXPLICIT_MODULES=NO

The workaround build passes.


Public failed CI run: https://github.com/pawicao/react-native-rncore-swap-repro/actions/runs/30450012497

React Native Version

0.87.0-rc.3, 0.87.0-rc.2

Affected Platforms

Build - MacOS

Output of npx @react-native-community/cli info

System:
  OS: macOS 15.7.4
  CPU: (11) arm64 Apple M3 Pro
  Memory: 920.84 MB / 18.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 24.16.0
    path: /Users/oskarpawica/.nvm/versions/node/v24.16.0/bin/node
  Yarn:
    version: 1.22.22
    path: /Users/oskarpawica/.nvm/versions/node/v24.16.0/bin/yarn
  npm:
    version: 11.13.0
    path: /Users/oskarpawica/.nvm/versions/node/v24.16.0/bin/npm
  Watchman: Not Found
Managers:
  CocoaPods:
    version: 1.16.2
    path: /opt/homebrew/bin/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 25.2
      - iOS 26.2
      - macOS 26.2
      - tvOS 26.2
      - visionOS 26.2
      - watchOS 26.2
  Android SDK:
    API Levels:
      - "34"
      - "36"
      - "36"
    Build Tools:
      - 33.0.1
      - 35.0.0
      - 36.0.0
      - 36.1.0
    System Images:
      - android-36.1 | Google Play ARM 64 v8a
      - android-36 | Google Play ARM 64 v8a
    Android NDK: Not Found
IDEs:
  Android Studio: 2025.3 AI-253.29346.138.2531.14876573
  Xcode:
    version: 26.3/17C529
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.18
    path: /usr/bin/javac
  Ruby:
    version: 3.3.7
    path: /Users/oskarpawica/.rbenv/shims/ruby
npmPackages:
  "@react-native-community/cli":
    installed: 20.2.0
    wanted: 20.2.0
  react:
    installed: 19.2.3
    wanted: 19.2.3
  react-native:
    installed: 0.87.0-rc.3
    wanted: 0.87.0-rc.3
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: true
iOS:
  hermesEnabled: true
  newArchEnabled: true

The local build uses CocoaPods 1.15.2 from Gemfile.lock. The command output reports the global CocoaPods installation as 1.16.2.

Stacktrace or Logs

PrecompileModule .../ExplicitPrecompiledModules/React-8KJ84LUSWCNOYHUBTIE0UD7ZW.scan

RCTBridgeModule.h:14:9: error: include of non-modular header inside framework module 'React.RCTBridgeModule': '.../RCTDeprecation/RCTDeprecation.h' [-Werror,-Wnon-modular-include-in-framework-module]
RCTConvert.h:19:9: error: include of non-modular header inside framework module 'React.RCTConvert': '.../yoga/Yoga.h' [-Werror,-Wnon-modular-include-in-framework-module]
UIView+React.h:12:9: error: include of non-modular header inside framework module 'React.UIView_React': '.../yoga/YGEnums.h' [-Werror,-Wnon-modular-include-in-framework-module]
RCTHermesInstanceFactory.h:8:9: error: include of non-modular header inside framework module 'React.RCTHermesInstanceFactory': '.../react/runtime/JSRuntimeFactoryCAPI.h' [-Werror,-Wnon-modular-include-in-framework-module]
RCTLayout.h:11:9: error: include of non-modular header inside framework module 'React.RCTLayout': '.../yoga/Yoga.h' [-Werror,-Wnon-modular-include-in-framework-module]
RCTShadowView.h:15:9: error: include of non-modular header inside framework module 'React.RCTShadowView': '.../yoga/Yoga.h' [-Werror,-Wnon-modular-include-in-framework-module]
RCTSurfaceRootShadowView.h:10:9: error: include of non-modular header inside framework module 'React.RCTSurfaceRootShadowView': '.../yoga/YGEnums.h' [-Werror,-Wnon-modular-include-in-framework-module]

** BUILD FAILED **

The following build commands failed:
  PrecompileModule .../ExplicitPrecompiledModules/React-8KJ84LUSWCNOYHUBTIE0UD7ZW.scan

MANDATORY Reproducer

https://github.com/pawicao/react-native-rncore-swap-repro

Screenshots and Videos

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions