In a React Native package.json, what do codegenConfig's name, type, jsSrcsDir and android.javaPackageName fields control?
answer
- codegenConfig lives in package.json
- name: prefix of generated files
- type: modules, components or all
- jsSrcsDir: where specs are searched
- javaPackageName: default com.facebook.fbreact.specs
basics
~20 scodegenConfig tells Codegen what to generate: name labels the generated C++ and Objective-C++ files, type selects modules, components or all, jsSrcsDir is the folder searched for specs, and android.javaPackageName sets the package of the generated Java spec classes.
solid answer
~40 s`codegenConfig` is a field in the app's or library's `package.json` that Codegen reads at build time. **`name`** names the generated output: files such as `<name>.h`, `<name>-generated.cpp` and, on iOS, `<name>JSI.h`, so it should be unique per package. **`type`** limits generation to `modules`, `components` or `all`. **`jsSrcsDir`** is the root folder Codegen searches for spec files; a spec outside it is simply not seen. **`android.javaPackageName`** sets the Java package of the generated abstract spec classes, such as `NativeBatteryHealthSpec`; without it they land in `com.facebook.fbreact.specs`. An optional `ios` block maps modules and components to their Objective-C classes. None of these fields affect the JavaScript bundle; they only steer native code generation.
code
json · 11 lines{
"name": "device-fleet-app",
"codegenConfig": {
"name": "BatteryHealthSpec",
"type": "modules",
"jsSrcsDir": "specs",
"android": {
"javaPackageName": "com.devicefleet.battery"
}
}
}go deeper
Know that codegenConfig in package.json tells Codegen where the specs are and what to generate.
Explain each field: name labels generated files, type selects modules or components, jsSrcsDir scopes the search, javaPackageName places the Java classes.
Diagnose missing generated classes by checking jsSrcsDir, type and javaPackageName first, and choose distinctive names so library outputs do not collide.
Standardise codegenConfig conventions across in-house native packages so generated artefacts stay predictable as the number of modules grows.
## Where the configuration lives Codegen is configured through a custom field, **`codegenConfig`**, in `package.json`. An app that contains its own Turbo Native Modules puts it in the app's `package.json`; a library that ships specs puts it in the library's. When the app builds, Codegen visits the app and its dependencies and uses each package's `codegenConfig` to decide what to generate for it. ## The four fields most teams set | Field | Controls | Example | |---|---|---| | `name` | The name of this Codegen configuration, used for generated file names and code | `"BatteryHealthSpec"` | | `type` | Whether to generate `modules`, `components` or `all` | `"modules"` | | `jsSrcsDir` | The root folder where specs are searched | `"specs"` | | `android.javaPackageName` | The Java package of generated Android spec classes | `"com.devicefleet.battery"` | ### `name` The generated C++ and Objective-C++ artefacts carry this name. On Android the JNI folder contains `<name>.h` and `<name>-generated.cpp`; on iOS the output includes `<name>/<name>.h`, `<name>/<name>-generated.mm` and `<name>JSI.h`. Two packages with the same `name` would produce colliding output, so libraries pick a distinctive one. It is **not** the module's runtime name; that comes from the string passed to `TurboModuleRegistry`. ### `type` - `modules` generates only Turbo Native Module code. - `components` generates only Fabric component code. - `all` generates both. With `modules`, no component renderer folders are produced; with `components`, none of the module files are. ### `jsSrcsDir` Codegen crawls this folder for files named like specs (`Native...` for modules, `...NativeComponent` for components). Point it at a narrow folder such as `specs` or `src/specs`: a spec placed elsewhere is never found and never generated, which later shows up as a missing class in native code. ### `android.javaPackageName` The abstract Java class for each module spec, named after the spec file with `Spec` appended, is generated in this package. Your Kotlin or Java module imports it from there. If the field is omitted, the generator falls back to `com.facebook.fbreact.specs`, which works but mixes your classes into a generic package and invites collisions between libraries. ## How the fields show up in the output With `name` set to `BatteryHealthSpec`, `type` to `modules`, `jsSrcsDir` to `specs` and `javaPackageName` to `com.devicefleet.battery`, an Android build of the app produces, under `android/app/build/generated/source/codegen`: - `java/com/devicefleet/battery/NativeBatteryHealthSpec.java`, the abstract class your Kotlin module extends; - `jni/BatteryHealthSpec.h` and `jni/BatteryHealthSpec-generated.cpp`, the C++ glue; - `schema.json`, the parsed description of every spec Codegen found. On iOS the equivalent output includes `BatteryHealthSpec/BatteryHealthSpec.h`, `BatteryHealthSpec/BatteryHealthSpec-generated.mm` and `BatteryHealthSpecJSI.h`. Reading these paths back is the fastest way to confirm that each field did what you intended. ## Apps versus libraries Every package that ships specs carries its own `codegenConfig`. When the app builds, Codegen processes the app's configuration and each linked dependency's, generating library code in that library's build folder. The app therefore never lists a library's specs; it only needs the library installed and linked. ## The optional `ios` block For iOS, `codegenConfig.ios` can map each module name to its Objective-C class (`className`), mark modules that must be set up on the main queue, and declare certain protocol conformances, and it can map component names to their classes. Those settings belong to the iOS implementation work rather than to the spec itself. ## Common mistakes 1. **Specs outside `jsSrcsDir`**: nothing is generated and no error explains why. 2. **`type: "components"` in a module library**: module interfaces are never produced. 3. **Reusing a generic `name`** across libraries: generated files collide. 4. **Forgetting `javaPackageName`**, then importing the spec class from the wrong package in Kotlin. 5. **Expecting the `name` to be the module's JavaScript name**: it only labels generated files. ## Summary `codegenConfig` steers native generation: `name` labels the output, `type` chooses modules, components or both, `jsSrcsDir` scopes the spec search, and `android.javaPackageName` places the Java spec classes. The module's runtime name is set elsewhere, in the spec's registry call and the native registration.
- Is codegenConfig.name the name JavaScript uses to load the module?No. `name` only labels the generated native files. JavaScript loads the module by the string literal passed to `TurboModuleRegistry.getEnforcing` or `get` in the spec, and that string must match what the native module registers.
- What happens if javaPackageName is omitted?The Java generator places spec classes in `com.facebook.fbreact.specs`. The module still works if your Kotlin or Java code imports the class from there, but a project-specific package is clearer and avoids name clashes between libraries that also omit it.
saying these in an interview costs you the question
- codegenConfig.name is the module name JavaScript passes to TurboModuleRegistry
- Codegen searches the whole repository for specs regardless of jsSrcsDir
- type: all is required for a module-only library
- codegenConfig changes how Metro bundles the JavaScript
- Without javaPackageName Codegen refuses to generate Android code