Skip to content

Codegen doesn't use autolinking on iOS #53501

@byCedric

Description

@byCedric

Description

With Expo SDK 54 around the corner, we significantly improved our autolinking behavior to support isolated modules better (see: https://kitten.sh/blog/autolinkings-broken-promise) and we fixed our internal dependency references across the whole Expo SDK.

We hoped to see significant DX improvements around this, for example, transitive dependencies are properly discovered, deduplicated, and autolinked through bun expo-modules-autolinking verify --json | jq. Meaning that we hoped to reduce the Expo Router installation instructions:

  • from: bun expo install expo-router react-native-safe-area-context react-native-screens expo-linking expo-constants expo-status-bar
  • to just: bun expo install expo-router.

In our test setup, we tested the following setup:

  • bun create expo ./test-linking --template blank@next
  • cd ./test-linking
  • bun expo install expo-router expo-dev-client

    Expo Router has proper peer dependencies to the required dependencies, and with all package managers installing peer dependencies automatically, users shouldn't need to run bun expo install expo-router react-native-safe-area-context react-native-screens expo-linking expo-constants expo-status-bar.

  • bun expo run ...
    • bun expo run android → ✅ Works as expected.
    • bun expo run ios → ❌ Fails due to missing header files for react-native-safe-area-context codegen'd files

After initial debugging, we found that Codegen on iOS is not using autolinking at all:

return Object.keys(dependencies).flatMap(dependency => {
. It's only performing a shallow pass on direct project dependencies and executes codegen for these dependencies.

This doesn't match the behavior of Android at all, where the output of autolinking seems to be used correctly (bun expo-modules-autolinking verify --json | jq).

Steps to reproduce

  1. bun create expo ./test-linking --template blank@next
  2. cd ./test-linking
  3. bun expo install expo-router expo-dev-client
  4. bun expo prebuild --platform ios
  5. Check if autolinking discovers correct (transitive) dependencies
    • bun expo-modules-autolinking verify --json | jq
  6. Check if codegen is running for the right dependencies (❌ not the case)
    • node node_modules/react-native/scripts/generate-codegen-artifacts.js --path $PWD --targetPlatform ios --outputPath ios
  7. bun expo run ios → ❌ Can't be built due to missing headers
  8. bun expo run android → ✅ Works fine

As an experiment to see if this is fixed by actually using the output of autolinking, I modifed the example repository with special code to do that (patch package). You can test this through the workaround branch.

It's basically an unsafe demonstration that when using the dependency information from autolinking, codegen is working as intended and the build is passing (through bun expo run ios), but it does resolve all build issues.


React Native Version

0.81.1

Affected Platforms

Runtime - iOS

Output of npx @react-native-community/cli info

info Fetching system and libraries information...
System:
  OS: macOS 15.6.1
  CPU: (12) arm64 Apple M2 Max
  Memory: 1.37 GB / 96.00 GB
  Shell:
    version: "5.9"
    path: /opt/homebrew/bin/zsh
Binaries:
  Node:
    version: 22.18.0
    path: ~/.nvm/versions/node/v22.18.0/bin/node
  Yarn:
    version: 1.22.22
    path: ~/.nvm/versions/node/v22.18.0/bin/yarn
  npm:
    version: 10.8.2
    path: /opt/homebrew/bin/npm
  Watchman: Not Found
Managers:
  CocoaPods:
    version: 1.16.2
    path: /Users/cedric/.rvm/gems/ruby-3.3.6/bin/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 24.5
      - iOS 18.5
      - macOS 15.5
      - tvOS 18.5
      - visionOS 2.5
      - watchOS 11.5
  Android SDK:
    API Levels:
      - "31"
      - "33"
      - "33"
      - "34"
      - "35"
      - "36"
    Build Tools:
      - 30.0.2
      - 30.0.3
      - 31.0.0
      - 33.0.0
      - 33.0.1
      - 34.0.0
      - 35.0.0
      - 36.0.0
    System Images:
      - android-30 | Google APIs ARM 64 v8a
      - android-31 | Google APIs ARM 64 v8a
      - android-33 | Google APIs ARM 64 v8a
      - android-34 | Google Play ARM 64 v8a
      - android-35 | Google Play ARM 64 v8a
    Android NDK: Not Found
IDEs:
  Android Studio: 2024.2 AI-242.23726.103.2422.12816248
  Xcode:
    version: 16.4/16F6
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.16
    path: /usr/bin/javac
  Ruby:
    version: 3.3.6
    path: /Users/cedric/.rvm/rubies/ruby-3.3.6/bin/ruby
npmPackages:
  "@react-native-community/cli": Not Found
  react:
    installed: 19.1.0
    wanted: 19.1.0
  react-native:
    installed: 0.81.1
    wanted: 0.81.1
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: Not found
  newArchEnabled: Not found
iOS:
  hermesEnabled: Not found
  newArchEnabled: Not found

Stacktrace or Logs

See image below

MANDATORY Reproducer

https://github.com/byCedric/react-native-codegen-ios-autolinking

Screenshots and Videos

Image

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