packages/react-native/scripts/ios-prebuild/__docs__/README.md
This directory contains scripts for prebuilding React Native itself into XCFrameworks for iOS and related platforms.
These scripts automate the process of building React Native as a Swift Package and packaging it into XCFrameworks that can be distributed and consumed by iOS applications. The build process creates optimized frameworks for multiple architectures and platforms.
The prebuild scripts are used to:
Run the prebuild script from the command line:
cd packages/react-native
node scripts/ios-prebuild
If no options are passed, the script executes all the steps in this order:
| Option | Alias | Type | Default | Description |
|---|---|---|---|---|
--setup | -s | boolean | - | Download and setup dependencies |
--build | -b | boolean | - | Build dependencies/platforms |
--compose | -c | boolean | - | Compose XCFramework from built dependencies |
--platforms | -p | array | ['ios', 'ios-simulator', 'mac-catalyst'] | Specify one or more platforms to build for |
--flavor | -f | string | Debug | Specify the flavor to build: Debug or Release |
--identity | -i | string | - | Specify the code signing identity to use for signing the frameworks |
--help | - | boolean | - | Show help information |
The build produces:
The build system consists of several components:
cli.jsThe main entry point that orchestrates the build process. It:
build.jsHandles the Swift Package build process. It:
xcodebuild commands with appropriate flagsBUILD_LIBRARY_FOR_DISTRIBUTION=YES for binary
compatibilitytypes.jsDefines TypeScript/Flow type definitions for:
BuildFlavor: Debug or Release configurationsDestination: Target platforms (iOS, iOS Simulator, Catalyst, Vision,
visionOS)ArchiveOptions: Configuration options for the build processutils.jsProvides utility functions including:
The build process uses specific xcodebuild flags:
BUILD_LIBRARY_FOR_DISTRIBUTION=YES: Enables module stabilitySKIP_INSTALL=NO: Ensures frameworks are properly installedDEBUG_INFORMATION_FORMAT="dwarf-with-dsym": Generates debug symbolsOTHER_SWIFT_FLAGS="-no-verify-emitted-module-interface": Skips interface
verification (useful for React Native modules due to the header structure not
beeing modular)The prebuilt XCFrameworks ship a headers-spec layout so that header imports resolve through plain header/framework search paths — there is no clang VFS overlay. The layout contract is defined and validated in code:
headers-spec.js: the executable layout contract (rules R1–R8) — which
namespaces are hoisted, which carry module maps, and how collisions are
rejected.headers-inventory.js: scans the source tree to build the live header
inventory that feeds the spec.headers-compose.js: emits the layout. emitReactFrameworkHeaders() writes
the React/ and bare-aliased headers into every slice's
React.framework/Headers, and buildReactNativeHeadersXcframework()
assembles the headers-only ReactNativeHeaders.xcframework carrying every
other namespace (incl. react/) plus the third-party dependency namespaces
(folly, glog, boost, fmt, double-conversion, fast_float). The
Hermes public headers (<hermes/...>) are folded in only on the SwiftPM
consumer side (ensureHeadersLayout); the published prebuild artifact does
not yet carry them (TODO in xcframework.js).The prebuild (xcframework.js) always produces:
React.xcframework — the compiled React core. Each slice's React.framework
carries the headers-spec layout (every <React/...> header + the framework
module map), which is what both CocoaPods and SwiftPM consume.ReactNativeHeaders.xcframework — headers-only; carries every other
namespace. Consumed by SwiftPM as a binaryTarget and by CocoaPods via the
React-Core-prebuilt pod (headers flattened onto the header search path).The React-Core-prebuilt pod vends React.xcframework (so <React/...> and
@import React; resolve through the framework module via
FRAMEWORK_SEARCH_PATHS) and flattens ReactNativeHeaders.xcframework's
headers into a top-level Headers/ exposed on the pod header search path (so
<react/...>, <yoga/...>, <folly/...> resolve). rncore.rb adds the
HEADER_SEARCH_PATHS entry to React-Core-prebuilt/Headers for podspec,
aggregate (main app), and third-party pod targets. No -ivfsoverlay flags are
added.
For consuming, debugging or troubleshooting when using Cocoapods scripts, you can use the following environment variables:
RCT_USE_PREBUILT_RNCORE: If set to 1, it will use the release tarball from
Maven instead of building from source.RCT_TESTONLY_RNCORE_TARBALL_PATH: TEST ONLY If set, it will use a local
tarball of RNCore if it exists.RCT_TESTONLY_RNCORE_VERSION: TEST ONLY If set, it will override the
version of RNCore to be used.RCT_SYMBOLICATE_PREBUILT_FRAMEWORKS: If set to 1, it will download the dSYMs
for the prebuilt RNCore frameworks and install these in the framework folders