Skip to content

feat(init): set up iOS with Swift Package Manager by default - #2881

Draft
chrfalch wants to merge 1 commit into
react-native-community:mainfrom
chrfalch:spm-default-init
Draft

chrfalch wants to merge 1 commit into
react-native-community:mainfrom
chrfalch:spm-default-init

Conversation

@chrfalch

Copy link
Copy Markdown

Summary

React Native plans to make Swift Package Manager the default iOS dependency setup in 0.89, with CocoaPods as an opt-out. Today init always sets up a new app with CocoaPods, so a new app does not get the default.

This PR changes init on macOS, for React Native 0.87 and later:

  1. After dependencies are installed, init runs React Native's own setup script: setup-apple-spm add --deintegrate --yes. It removes the template's CocoaPods setup and adds the Swift Package Manager setup. The pod install step and its prompt do not run.
  2. A new flag, --skip-spm, keeps the CocoaPods setup. --install-pods then works as before.
  3. --install-pods true without --skip-spm is an error where the setup would run, so scripts see the conflict instead of a silent change.
  4. If the setup fails, init prints a warning and the command to retry, and finishes. This is the same as a failed pod install today.
  5. With --skip-install, init prints the setup command to run later.

Nothing changes on Linux or Windows, or for React Native 0.86 and earlier. With --template or an out-of-tree --platform-name, init does not know the React Native version up front: --install-pods true keeps CocoaPods there, and otherwise the setup runs if the installed React Native has the script.

run-ios and build-ios already detect a Swift Package Manager project (#2858), so they work on the new app without a Podfile install.

Depends on: react/react-native#59368 (spm deinit, the way back to CocoaPods for an existing app). This PR is a draft until that lands. The code does not call deinit.

Test Plan

Unit tests:

yarn jest packages/cli/src/commands/init

Result: 7 suites, 96 tests pass. New: __tests__/spm.test.ts, __tests__/init.test.ts (through initialize), __tests__/printRunInstructions.test.ts. yarn lint and yarn build:ts pass.

End-to-end, with a local build of this branch, Xcode 27.1, CocoaPods 1.16.2:

Case Result
init on RN 0.88.1 Swift Package Manager set up, no CocoaPods references left, no pod text, simulator build succeeds
init on RN 0.87.1 same
init --skip-spm CocoaPods setup kept, pod instructions printed
init --install-pods true exits 1 before the project folder is made
init with no pod on PATH warning and retry command, project left on CocoaPods

Not tested: React Native 0.89 (not released).

Checklist

  • Documentation is up to date.
  • Follows commit message convention described in CONTRIBUTING.md.
  • For functional changes, my test plan has linked these CLI changes into a local react-native checkout (instructions). Tested with a local CLI build on fresh apps from released React Native versions instead.

On macOS, for React Native 0.87 and later, `init` now runs React
Native's Swift Package Manager setup (`setup-apple-spm add
--deintegrate --yes`) after dependencies are installed, instead of
installing CocoaPods. `--skip-spm` keeps the CocoaPods setup.
`--install-pods true` without `--skip-spm` is an error where the
setup would run. A failed setup prints a warning and a retry
command; init still finishes.
@github-actions github-actions Bot added docs Documentation change feature labels Oct 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Documentation change feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant