From b217e702fc78927ae835bc9b0a2510a1c93a4b30 Mon Sep 17 00:00:00 2001 From: Christian Falch Date: Wed, 19 Aug 2026 09:09:54 +0200 Subject: [PATCH] Docs: correct how SwiftPM consumes the prebuilt React headers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary: `ios-prebuild/__docs__/README.md` said `React.framework`'s headers-spec layout "is what both CocoaPods and SwiftPM consume". That is right for CocoaPods and misleading for SwiftPM: `React.xcframework` is not a member of the Swift package graph at all, so nothing on the SwiftPM side reads its framework module map. What actually happens is a staging step on the consumer side — `stageReactHeadersTarget` in `scripts/spm/flavored-frameworks.js` copies `React.framework/Headers` into `ReactHeadersTarget/include/React` and rewrites `framework module React` to a plain `module React`, which is then vended as the `ReactHeaders` target. The prebuild output is still the source of those headers, which is why the sentence was nearly right; the consumption path is what differs. Says so, and keeps the CocoaPods half explicit about `FRAMEWORK_SEARCH_PATHS` so the two paths read as the distinct mechanisms they are. ## Changelog: [Internal] - Clarify that SwiftPM consumes the prebuilt React headers through a staged `ReactHeaders` target, not through the XCFramework's module map ## Test Plan: Docs only. Verified against `scripts/spm/generate-spm-package.js`, whose generated `ReactNative` manifest declares exactly three headers-only products and no runtime `binaryTarget`, and against `stageReactHeadersTarget`, which does the copy and the module-map rewrite only after Debug and Release are asserted to expose identical headers. Prettier clean — the file was formatted before this change and still is. Co-Authored-By: Claude Opus 5 --- .../react-native/scripts/ios-prebuild/__docs__/README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/react-native/scripts/ios-prebuild/__docs__/README.md b/packages/react-native/scripts/ios-prebuild/__docs__/README.md index c411934c1742..70411582212b 100644 --- a/packages/react-native/scripts/ios-prebuild/__docs__/README.md +++ b/packages/react-native/scripts/ios-prebuild/__docs__/README.md @@ -138,7 +138,13 @@ The prebuild (`xcframework.js`) always produces: - `React.xcframework` — the compiled React core. Each slice's `React.framework` carries the headers-spec layout (every `` header + the framework - module map), which is what both CocoaPods and SwiftPM consume. + module map). CocoaPods consumes that layout directly, through + `FRAMEWORK_SEARCH_PATHS`. SwiftPM consumes the same headers indirectly: the + XCFramework is not a member of the Swift package graph, so the consumer side + stages a copy of `React.framework/Headers` into + `ReactHeadersTarget/include/React` and rewrites `framework module React` to a + plain `module React`, vended as the `ReactHeaders` target (see + `spm-header-paths-contract.md` in the SwiftPM docs). - `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).