Skip to content

Commit 6b1c23e

Browse files
chrfalchclaude
andcommitted
feat(spm): B1 flavor architecture — per-config linking + RN-owned embed, no pin
Flavored prebuilt binaries (React, hermes-engine, ReactNativeDependencies) leave the SwiftPM package graph. The generated ReactNative package vends only headers-only products (ReactHeaders / ReactNativeHeaders / ReactNativeDependenciesHeaders); both flavors' framework trees are staged at add/update time and a per-configuration RN_SPM_FLAVOR build setting selects one at build time via sdk-conditional link settings; embedding + codesign is an RN-owned script phase with declared per-config outputs. A Debug/Release configuration switch is green and flavor-correct on the FIRST build, both directions, with zero user action. The flavor pin, swap sandwich, hard-fail + converge, and OBJROOT cache surgery are deleted (swap-flavor.js and its test suites removed; --flavor gone from the CLI surface). New flavored-frameworks.js owns staging and module-map relocation. Verified: 448 spm unit tests green; Expo E2E on 0.87.0-nightly-20260710-b1test (existing app + Swift source packages + precompiled frameworks via the flavoredFrameworks contract): repeated CLI + GUI config flips green and nm-flavor-correct first build every time, codesign --deep --strict clean, SwiftOnoneSupport structurally moot, clean migration from the previous architecture. Untested there: custom configuration names, device/Archive. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent b58841c commit 6b1c23e

29 files changed

Lines changed: 2597 additions & 3695 deletions

packages/react-native/react-native.config.js

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -124,10 +124,6 @@ const spmCommand /*: Command */ = {
124124
description:
125125
'React Native version (e.g. 0.80.0). Defaults to the version in node_modules/react-native/package.json.',
126126
},
127-
{
128-
name: '--flavor <string>',
129-
description: 'Artifact flavor: debug or release.',
130-
},
131127
{
132128
name: '--yes',
133129
description: 'Skip the dirty-pbxproj confirmation prompt.',
@@ -152,8 +148,7 @@ const spmCommand /*: Command */ = {
152148
{
153149
name: '--artifacts <path>',
154150
description:
155-
'[advanced] Local artifact source: a .xcframework file (used directly, ' +
156-
'no download) or a directory (cache dir to read/download into).',
151+
'[advanced] Local artifact root containing complete debug/ and release/ slots.',
157152
},
158153
{
159154
name: '--download <string>',
@@ -172,7 +167,6 @@ const spmCommand /*: Command */ = {
172167
}
173168
const stringOpts /*: Array<[string, string]> */ = [
174169
['version', '--version'],
175-
['flavor', '--flavor'],
176170
['productName', '--product-name'],
177171
['xcodeproj', '--xcodeproj'],
178172
['artifacts', '--artifacts'],

packages/react-native/scripts/codegen/templates/Package.swift.spm-template

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,15 @@
1212

1313
import PackageDescription
1414

15-
// React headers need NO search paths: React/react namespaces come from the
16-
// React binaryTarget (auto -F; headers + module map inside the framework),
15+
// React headers need NO search paths: the React module comes from the
16+
// invariant ReactHeaders Clang target,
1717
// every other RN namespace from the ReactNativeHeaders binaryTarget
1818
// (pure-RN), the third-party deps namespaces (folly/glog/boost/...) from the
1919
// ReactNativeDependenciesHeaders sidecar, and the per-app generated headers
2020
// from the ReactAppHeaders target below — all auto-served by SPM through
2121
// product/target dependencies.
2222
let headersDep: [Target.Dependency] = [
23+
.product(name: "ReactHeaders", package: "ReactNative"),
2324
.product(name: "ReactNativeHeaders", package: "ReactNative"),
2425
.product(name: "ReactNativeDependenciesHeaders", package: "ReactNative"),
2526
"ReactAppHeaders",
@@ -45,10 +46,7 @@ let package = Package(
4546
targets: [
4647
.target(
4748
name: "ReactCodegen",
48-
dependencies: [
49-
.product(name: "ReactNative", package: "ReactNative"),
50-
.product(name: "ReactNativeDependencies", package: "ReactNative"),
51-
] + headersDep,
49+
dependencies: headersDep,
5250
path: "ReactCodegen",
5351
exclude: ["ReactCodegen.podspec"],
5452
publicHeadersPath: ".",

0 commit comments

Comments
 (0)