Repository navigation
[0.88] [iOS][SPM] Derive the generated manifests' iOS platform floor from the app (+2 prerequisites) #1414
Copy link
Copy link
Closed
Labels
Type Pick RequestPick requests to include commits inside a React Native releasePick requests to include commits inside a React Native release
Description
Activity
- addedType Pick RequestPick requests to include commits inside a React Native releasePick requests to include commits inside a React Native release
on Sep 15, 2026 Thank you for opening a new React Native Pick Request.
These are the criteria we follow when accepting or rejecting a code change into a React Native release branch (source).
If your Pick Request does not satisfy the criteria below, please close it as it will not be considered.
✅ Which Pick Requests we accept
- ✅ Fixes for regressions to core APIs. Examples:
- A core component is behaving differently between versions 0.X and 0.X-1
- The
TurboModule.getEnforcingfunction is throwing an unexpected assertion error.
- ✅ Fixes to bugs in core React Native. Examples:
- Breakpoints in React Native DevTools not working correctly in the debugger
- Fast Refresh not working as expected
- Metro bundler not starting properly or ignoring the configuration file
- Buttons that are not clickable
- ✅ Fixes to APIs used by third-party libraries and out-of-tree platforms. Examples:
- An API used by
react-native-macosis not behaving as expected or is regressing
- An API used by
- ✅ Bump of patch version of dependencies. Example:
- Bump Gradle from 8.11.0 to 8.11.1
- ✅ Fixes for low/high severity security vulnerabilities. Example:
- Bump Gradle from 8.11.0 to 8.12.0 if there is a security vulnerability in 8.11 and no 8.11.x version contains the same fix.
- ✅ Fixes and reverts of accidental breaking changes. Example:
- Reverting or fix-forwarding a Kotlin migration of a file (e.g.
ReactRootView.java) if it is causing a breaking change for the React Native ecosystem.
- Reverting or fix-forwarding a Kotlin migration of a file (e.g.
- ✅ Performance improvements. Examples:
- Fixing unnecessary re-renders in FlatList.
- ✅ Any Pick Request if the release is still in RC0 (after RC1, the previously listed criteria apply)
❌ Which Pick Requests we don't accept
- ❌ Any Pick Request that introduces a breaking change after RC1. Example:
- A bugfix that contains a refactoring, resulting in changes to the public API of a class
- ❌ Any Pick Request that introduces a new feature after RC1. Example:
- A commit that introduces a new API or a specific feature for a component.
- ❌ Bump of major or minor version of dependencies. Examples:
- Bump Gradle from 8.11.0 to 8.12.0
- Bump Gradle from 8.11.0 to 9.0.0
- ❌ Bump of a dependency to a pre-release version. Example:
- Bump Gradle from 8.11.0 to 8.11.1-beta.1
- ❌ Any Pick Request that introduces changes to the React Native testing infrastructure after RC1. Examples:
- Changes to GitHub Actions workflows to optimize them, even if they are on main.
- Changes to the logic used to publish packages to NPM or Maven Central
- ❌ Pick Request composed of multiple commits that have several merge conflicts.
- If your Pick Request is too complex to apply to the release branch, it will be rejected.
- ❌ Any non-critical improvement that landed on main.
- These will generally ship in the following version unless they fit one of the criteria above.
- ❌ Any Pick Request considered a "nice to have".
- Even one-line changes carry a risk of destabilizing and further delaying the release.
ℹ️ What makes for a good Pick Request
In order for your Pick Request to be considered, please do the following:
- ℹ️ Limit your Pick Request to one commit from
main, or one PR against the release branch. - ℹ️ Include a clear explanation of why your Pick Request should be considered, ideally referencing one of the criteria above.
- ℹ️ Target only one minor version of React Native (e.g. [0.76]). To have your Pick Request applied to more versions, please open separate Pick Requests.
- ✅ Fixes for regressions to core APIs. Examples:
- changed the title
[-][0.88] [iOS][SPM] Derive the generated manifests' iOS platform floor from the app[/-][+][0.88] [iOS][SPM] Derive the generated manifests' iOS platform floor from the app (+2 prerequisites)[/+]on Sep 15, 2026 Picked manually into
0.88-stable:PR Commit on 0.88-stable#58290 38302c95345#58362 903c4ab7636#58379 6069149f257All three applied without conflicts. SPM test suites pass: 1001 tests across 21 suites.
- moved this from Inbox to Done / Picked in React Native 0.88 Releases
on Sep 15, 2026
Metadata
Metadata
Assignees
Labels
Type Pick RequestPick requests to include commits inside a React Native releasePick requests to include commits inside a React Native release
Type
Projects
- StatusShow more project fieldsDone / Picked
Target Branch
0.88
Link to commit or PR to be picked
Pick in this order (oldest first):
1cfc5f29a00— Derive an SPM library's Swift name from its podspec25f48bd72fd— Run SPM-generated shell scripts under bash, not/bin/sh92564f33fda— Derive the generated manifests' iOS platform floor from the app (D119653699)Description
The change we actually want is #58379. The other two are prerequisites, so the request covers all three.
Why #58379 is needed
The SwiftPM manifests React Native generates (the
Autolinkedaggregate, the per-dependency synth packages and the scaffolded community packages) hardcodeplatforms: [.iOS(.v15)]. SwiftPM refuses to link a product whose minimum platform is above the depending target's, so any self-managed package with a higher floor cannot be autolinked.Every Expo package declares iOS 16.4, so a stock Expo app fails at build time:
The app itself is correct (
IPHONEOS_DEPLOYMENT_TARGET = 16.4). Only the generated manifests disagree. The fix derives the floor from the app's own deployment target, clamped to React Native's minimum (15.1).Why the prerequisites
#58290 is a hard dependency. #58379 imports
findPodspecsandreadPodspecCachedfromscripts/spm/read-podspec.js. On0.88-stablethat module exports onlyreadPodspec, so the pick does not build without #58290 first. Cherry-picking #58379 alone conflicts ingenerate-spm-autolinking.jsandscaffold-package-swift.js.#58362 is taken to avoid a conflict. It and #58379 both modify
scripts/spm/generate-spm-xcodeproj.js. Not a functional dependency, but skipping it makes #58379 conflict there.#58425 is deliberately not taken. It is chronologically between #58362 and #58379 and touches
scripts/spm/, but shares no file with #58379 (it changesdownload-spm-artifacts.js, the CocoaPods ruby helpers and the Gradle Kotlin plugin). It is a separate concern and is not required here.Risk
The chain is larger than a typical post-RC1 pick, so worth being explicit about the blast radius.
All of the code these commits change lives under
packages/react-native/scripts/spm/plusscripts/setup-apple-spm.js. That tree is required only bysetup-apple-spm.js, which is a manual entry point (node node_modules/react-native/scripts/setup-apple-spm.js [action]). It is not wired intopod installor any build phase. The only SPM code that runs unconditionally is the CocoaPods hookSPM.apply_on_post_install, which iterates a dependency map that stays empty unless a podspec declares an SPM dependency, and none of these commits touch it.So an app that does not opt into SwiftPM cannot execute a line any of these change.
The remaining files in #58290 are
packages/rn-tester/andpackages/react-native-test-library/, which are React Native's own fixtures and are not shipped.On size: #58290 reads as +3386/-912 across 26 files, but roughly 2264 of those additions are test files and ~143 are docs. The production delta is around +900/-325.
Two behaviour changes that do land, both only for SwiftPM users:
swiftpmConfig.nameas the fix, where previously colliding names were auto-corrected. The old behaviour invented a module name no#importcould predict, so the error is the better outcome, but it is new.SCAFFOLDER_VERSIONbumps to 20, so existing scaffolds regenerate with the new floor on the nextspm add/spm update.Prerequisite audit
Checked against a full (unshallowed)
mainhistory: every SPM commit preceding #58290 is already on0.88-stable(#58292, #58060, #58044, #58033, #58087, #58059, #58034, #58035). The chain starts cleanly at #58290 and is exactly these three.