Skip to content

project.ios.automaticPodsInstallation default of true never applies unless project.ios is explicitly declared in react-native.config.js #2825

Description

@schteff

Environment

Output of npx react-native info from a freshly created, unmodified RN 0.87.0 project
(npx @react-native-community/cli@latest init Fresh87 --version latest, pods installed):

System:
  OS: macOS 26.5.1
  CPU: (16) arm64 Apple M3 Max
  Memory: 2.17 GB / 48.00 GB
  Shell: Unknown
Binaries:
  Node:
    version: 26.7.0
    path: /opt/homebrew/bin/node
  Yarn:
    version: 1.22.22
    path: /opt/homebrew/bin/yarn
  npm:
    version: 11.19.0
    path: /opt/homebrew/bin/npm
  Watchman:
    version: 2026.07.27.00
    path: /opt/homebrew/bin/watchman
Managers:
  CocoaPods:
    version: 1.14.3
    path: /usr/local/bin/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 25.5
      - iOS 26.5
      - macOS 26.5
      - tvOS 26.5
      - visionOS 26.5
      - watchOS 26.5
  Android SDK: Not Found
IDEs:
  Android Studio: 2025.2 AI-252.25557.131.2521.14344949
  Xcode:
    version: 26.6/17F113
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 19.0.2
    path: /Users/me/Library/Java/JavaVirtualMachines/corretto-19.0.2/Contents/Home/bin/javac
  Ruby:
    version: 2.6.10
    path: /usr/bin/ruby
npmPackages:
  "@react-native-community/cli":
    installed: 20.2.0
    wanted: 20.2.0
  react:
    installed: 19.2.3
    wanted: 19.2.3
  react-native:
    installed: 0.87.0
    wanted: 0.87.0
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: true
iOS:
  hermesEnabled: true
  newArchEnabled: true

Two notes on that output, so it isn't misread:

  • info reports Shell: Unknown and probes without sourcing the login shell, so the Ruby 2.6.10 /
    CocoaPods 1.14.3 at /usr/local/bin/pod lines are macOS system defaults, not the toolchain used
    here. Every pod install in this report ran under CocoaPods 1.16.2 on Ruby 3.3.0 via
    bundle exec, and succeeded (45 s, 87 pods).
  • Android SDK: Not Found is unrelated noise for this iOS-only issue.

The bug is not environment-specific: the same resolution result is produced by the schema alone
(see the harness under "Reproducible Demo"), and the relevant code is unchanged in
@react-native-community/cli 17.x → 20.2.0 and on main.

Description

Since #2602 ("install Cocoapods by default in all projects"), the schema declares
automaticPodsInstallation: t.bool().default(true) and
docs/projects.md
documents Default: true. In practice that default is unreachable for any project that does not
explicitly declare a project.ios block — which is every project created by init, since the
template ships no react-native.config.js and generation of that file was removed in #2203.

Cause: the ios object uses a literal default, which joi returns as-is without descending into
it, so the inner .default(true) never runs:

For contrast, the sibling project key at
schema.ts#L175
uses a bare .default(), which is why project is populated while project.ios arrives as {}.

#2602's own Test Plan states: "With empty react-native.config.js Cocoapods should still install."
That is precisely the case that does not install.

User-visible effect. Automatic installation never triggers, so after adding or updating a native
dependency, run-ios builds against stale Pods: the build succeeds and the app launches with the
new native module absent from the binary, failing only at runtime. Meanwhile pod install — the
actual remedy — prints React Native's own DEPRECATION NOTICE telling users not to run it manually
and to use yarn ios instead, i.e. the command that silently skips pod installation. This loop was
described once by a user in react/react-native#54553
(react/react-native#54553 (comment)) but never filed here.

Reproducible Demo

npx @react-native-community/cli@latest init Awesome --version latest   # answer "y" to "install CocoaPods now?"
cd Awesome

npx react-native config | jq '.project.ios.automaticPodsInstallation'
# → null            (expected: true)

npx react-native run-ios          # baseline: builds and launches fine

npm i react-native-safe-area-context
grep -c safe-area-context ios/Podfile.lock     # → 0

npx react-native run-ios
#   no "Installing CocoaPods dependencies" step
#   build succeeds, app launches
grep -c safe-area-context ios/Podfile.lock     # → 0   (pods never regenerated; module not linked)

cat > react-native.config.js <<'EOF'
module.exports = {project: {ios: {automaticPodsInstallation: true}}};
EOF

npx react-native config | jq '.project.ios.automaticPodsInstallation'   # → true
npx react-native run-ios
#   "Installing Ruby Gems" → "Installing CocoaPods dependencies with New Architecture"
grep -c safe-area-context ios/Podfile.lock     # → 10  (works as documented)

Schema-level proof, no project required:

const s = require('@react-native-community/cli-config/build/schema');
const p = (input) => s.projectConfig.validate(input).value.project;

p(undefined)            // { ios: {}, android: {} }
p({})                   // { ios: {}, android: {} }   ← #2602's test-plan case
p({dependencies: {}})   // { ios: {}, android: {} }
p({project: {}})        // { ios: {}, android: {} }
p({project: {ios: {}}}) // { ios: { automaticPodsInstallation: true, assets: [] }, ... }

Expected behaviour

automaticPodsInstallation resolves to true for projects with no react-native.config.js, or with
one that omits project.ios — matching the documentation and the intent of #2602.

Suggested fix

Either of these; both verified against joi 17.13.3:

  1. Bare default in the schema, so joi applies the inner defaults — schema.ts:161
    (and android at :173 for consistency):

    -        .default({}),
    +        .default(),

    Joi.object({flag: Joi.bool().default(true)}).default(){flag: true}, whereas
    .default({}){}.

  2. Or an explicit fallback in cli-config-apple/src/config/index.ts:54:

    -      automaticPodsInstallation: userConfig.automaticPodsInstallation,
    +      automaticPodsInstallation: userConfig.automaticPodsInstallation ?? true,

Docs nit (same area)

docs/projects.md still states "Starting from React Native 0.73, CLI's init command scaffolds the
project with react-native.config.js file with this value set to true by default"
. That generation
was removed in #2203 (Dec 2023), and no template ships the file
(facebook/react-native ≤ 0.75, react-native-community/template 0.76 – 0.87).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions