When does React Native's Codegen run on Android and on iOS, and why can a newly added or edited spec still leave the native build missing its generated interface?
answer
- part of the native build, not Metro
- Gradle: generateCodegenArtifactsFromSchema
- iOS: pod install and a script phase
- new spec on iOS: pod install again
- run it by hand to inspect output
basics
~20 sCodegen runs during native builds: on Android through the generateCodegenArtifactsFromSchema Gradle task, on iOS during pod install and a CocoaPods build phase. A spec is missed when misnamed or outside jsSrcsDir, or, on iOS, added without re-running pod install.
solid answer
~40 sCodegen is part of the **native** build, never of Metro. On **Android**, the React Native Gradle plugin's `generateCodegenArtifactsFromSchema` task runs automatically on every build, for the app and every linked dependency, writing to `android/app/build/generated/source/codegen` (and to each library's own `build` folder). On **iOS**, `pod install` runs `generate-codegen-artifacts.js`, and CocoaPods adds a script phase that runs Codegen during builds; the list of spec files that phase watches is written at `pod install` time, so after **adding** a spec you re-run `pod install`. When the generated interface is missing, check in order: the file name starts with `Native`, it sits under `jsSrcsDir`, `type` includes `modules`, the build shows no `Module <name>:` parser error, and on iOS the pods were reinstalled. `./gradlew generateCodegenArtifactsFromSchema` or `npx @react-native-community/cli codegen` shows what is actually generated.
code
bash · 9 lines# Android: generate and inspect Codegen output
cd android && ./gradlew generateCodegenArtifactsFromSchema
ls app/build/generated/source/codegen/java
# iOS: regenerate after adding a spec file
cd ios && bundle exec pod install
# Either platform, without a full build
npx @react-native-community/cli codegen --platform androidgo deeper
Remember that Codegen runs during the native Android or iOS build, not when JavaScript reloads.
Name the mechanisms: the generateCodegenArtifactsFromSchema Gradle task, pod install with generate-codegen-artifacts.js, the build script phase, and the CLI for manual runs.
Diagnose a missing generated interface by separating discovery, parser and integration failures, and remember the iOS pod install step after adding a spec.
Make Codegen output visible in CI, for example by running it explicitly on spec changes, so contract drift is caught before a platform build fails late.
## Codegen is a native build step React Native's **Codegen** turns specs into C++ and platform interfaces, and native compilers need those files before they can compile your module. So Codegen runs as part of the **native build**, invoked by Gradle on Android and by CocoaPods and Xcode on iOS. Metro, which bundles JavaScript, never runs it; a JavaScript reload never regenerates anything. React Native's docs put it simply: Codegen is invoked automatically every time an iOS or Android app is built. ## Android - The **React Native Gradle plugin** provides the `generateCodegenArtifactsFromSchema` task and runs it automatically as part of building the app. - It processes the app and **every linked dependency**: the app's output goes to `android/app/build/generated/source/codegen`, and a library's to `node_modules/<library>/android/build/generated/source/codegen`. - The output holds a `java` folder with the abstract spec classes, a `jni` folder with the C++ glue, and a `schema.json` describing what Codegen parsed. - You can run the task on its own from the `android` folder to inspect the result: `./gradlew generateCodegenArtifactsFromSchema`. ## iOS - During **`pod install`**, React Native's CocoaPods scripts run `generate-codegen-artifacts.js` for the iOS target, producing the Objective-C++ and C++ output and the `ReactCodegen` pod. - CocoaPods also adds a **script phase** that runs Codegen during Xcode builds. - The list of spec files that phase depends on is computed when `pod install` runs, by searching `jsSrcsDir` for `Native*` and `*NativeComponent` files. A spec **added afterwards** is not in that list, so the reliable step after adding or renaming a spec is to run `pod install` again. - The same script can be run by hand: `node node_modules/react-native/scripts/generate-codegen-artifacts.js --path . --outputPath ios/ --targetPlatform ios`. ## The Codegen CLI For both platforms, `npx @react-native-community/cli codegen` reads `codegenConfig` from the current `package.json` and generates code, with `--platform` and `--outputPath` options. It is the quickest way to see which interfaces a spec will produce before writing native code. ## Why a generated interface can be missing | Symptom | Likely cause | Check | |---|---|---| | Native compile error: `NativeBatteryHealthSpec` not found, no Codegen error | Spec file not discovered | File starts with `Native`, sits under `jsSrcsDir`, is not a `.d.ts` | | Same, and `codegenConfig.type` is `components` | Module generation disabled | Set `type` to `modules` or `all` | | Build stops with `Module NativeBatteryHealth: ...` | Spec breaks a parser rule | Read the message; it names the rule | | iOS only: new spec ignored | Pods not reinstalled after adding it | Run `pod install` | | Android: Kotlin imports fail | Wrong package | Match `android.javaPackageName` | | Old signature still generated | Build did not re-run Codegen | Rebuild the native app, not just reload JavaScript | The `schema.json` file Codegen writes next to its Android output is a useful witness: it lists every module and method Codegen parsed. If your module is missing from it, the spec was never discovered; if it is present with the old signature, the native build has not re-run Codegen since you edited the spec. ## A diagnostic routine 1. **Run Codegen by hand** for the failing platform and look for your class in the output. 2. If it is absent, the problem is **discovery**: name, folder, `type`. 3. If a parser error appears, fix the spec rule it names. 4. If the class is present but the build still fails, the problem is **integration**: the package name on Android, or stale pods on iOS. 5. Rebuild the native app; reloading JavaScript cannot add or change native code. ## Libraries that ship generated code Most libraries leave generation to the app's build. Some ship pre-generated output instead, through a `codegenConfig` option for including generated code; that is a packaging decision, and it ties the output to the React Native version the library generated with. ## Summary Codegen runs inside the native build: automatically through a Gradle task on Android, and through `pod install` plus a build script phase on iOS. A missing interface usually means the spec was never discovered or failed a parser rule, or, on iOS, that the pods were not reinstalled after the spec was added.
- Why doesn't a fast refresh pick up a new method added to the spec?Fast refresh reloads JavaScript through Metro, but the new method also needs regenerated native interfaces and a native implementation compiled into the app. Codegen runs only in the native build, so you must rebuild the Android or iOS app (and on iOS re-run pod install if you added a new spec file).
- Where does Codegen put a library's generated Android code?In the library's own build folder under `node_modules`, for example `node_modules/<library>/android/build/generated/source/codegen`, because the Gradle task runs for every linked dependency during the app's build. The app's own specs generate into `android/app/build/generated/source/codegen`.
saying these in an interview costs you the question
- Codegen runs whenever Metro rebuilds the JavaScript bundle
- A misnamed spec file always produces a clear Codegen error
- On iOS a newly added spec is picked up without re-running pod install
- Reloading JavaScript is enough after changing a spec's method signature
- Library specs must be generated by hand before the app can build