Codegen is an automatic code generation tool in the React Native ecosystem that creates TypeScript, C++, and Objective-C wrappers based on declarative specifications of native module interfaces. The developer only describes method signatures and parameter types in a JavaScript file, while Codegen generates all the bridging code between JS and the native side. According to React Native Documentation (2025), Codegen reduces native module development time by an average of 60% by automating routine code.
Key Takeaways
Codegen (short for Code Generator) is a command-line utility included in React Native that automatically generates bridging code for interaction between JavaScript and native platforms (iOS, Android). Codegen is an integral part of the new React Native architecture and is used for both Fabric (renderer) and TurboModules (native modules).
The main idea of Codegen is separation of concerns: the developer describes "what" a function should do (its signature), and Codegen generates "how" it will be passed to the native side. This eliminates the need to manually write C++ wrappers for JSI, Objective-C stubs for iOS, and Java classes for Android. A single source of truth — the TypeScript specification — ensures that types match at all levels, eliminating a whole class of errors related to type mismatches between JS and native code.
Codegen was introduced with the first stable version of the new React Native architecture (0.70+) and has since become a mandatory tool for creating native modules. Without Codegen, developers would have to manually write JSI Host Objects, requiring deep knowledge of C++ and understanding of the internals of JavaScript engines.
Before Codegen, developing a native module for React Native involved three steps: writing a JavaScript interface, implementing the native module in Java/Objective-C, and manually writing the bridge. When a method signature changed, all three files had to be updated synchronously. Codegen automates this routine: changes are made only to the TypeScript specification, and everything else is regenerated.
Codegen integrates into the React Native build process through Metro and CocoaPods. When building, Codegen analyzes TypeScript specifications, generates C++ and platform files, and places them in the build directory. This means the generated code always matches the current specifications and requires no manual updates.
The Codegen workflow consists of three stages: parsing specifications, building an intermediate representation, and generating target files. Each stage is isolated, making it easy to add support for new platforms or generation languages.
In the first stage, Codegen reads specification files in TypeScript or Flow format. The specification describes the native module interface: method names, parameter types, and return types. Codegen supports primitive types (number, string, boolean) as well as complex ones — objects, arrays, Promise, and Callback. Specifications are stored in .ts or .js files in a special project directory.
In the second stage, Codegen builds an Abstract Syntax Tree (AST) from the parsed specifications. The AST represents the data structure in a neutral format not tied to any specific generation language. This allows generating C++ code for Fabric, Objective-C for iOS, and Java for Android from a single AST — no additional work is required to support all platforms.
In the third stage, Codegen uses a template engine (based on Mustache) to generate target platform files. Each template handles a specific file type: C++ header (.h), implementation (.cpp), Objective-C protocol (.h) or implementation (.mm), Java class. Templates ship with React Native but can be customized for specific project needs.
// NativeCalculator.ts — native module specification
import { TurboModule, TurboModuleRegistry } from 'react-native'
import { Double } from 'react-native/Libraries/Types/CodegenTypes'
export interface NativeCalculatorSpec extends TurboModule {
add(a: Double, b: Double): Double
multiply(a: Double, b: Double): Double
}
export default TurboModuleRegistry.<NativeCalculatorSpec>('NativeCalculator')
In this example, the specification describes the NativeCalculator module with two methods: add and multiply. Both accept Double and return Double. The string 'NativeCalculator' in TurboModuleRegistry specifies the module name that will be used on the native side. Codegen based on this specification will generate all the necessary files for Fabric and TurboModules.
In the context of Fabric (the new React Native renderer), Codegen plays a special role. Fabric requires that every native UI component has a C++ representation that can be created and managed through JSI. Codegen generates these C++ representations automatically based on component specifications.
For UI components, Codegen generates not only the C++ Shadow Node class but also platform-specific representations. For example, for a custom Button component on iOS, Codegen creates an Objective-C class that registers the component in Fabric and links it to the C++ Shadow Node. The developer only needs to describe the component properties (color, size, handlers) in the TypeScript specification.
Codegen supports both direct and reverse data transfer. Direct Events (e.g., onPress) are generated as C++ structures with fields that are automatically serialized when passed to JS. EventEmitter allows the native side to send events to JS without a request from JS. Codegen generates typed wrappers for both directions, eliminating field name mismatch errors.
| Component | Specification (TypeScript) | C++ Generation | Platform Generation |
|---|---|---|---|
| Method | add(a: Double): Double | JSI Host Function | NativeMethod on iOS/Android |
| Property | color: String | Shadow Node prop | UIView/View property |
| Event | onPress: () => Void | Event struct | UIControl/View callback |
| Constant | PI: Double | Const getter | Constants export |
Library developers can ship Codegen specifications with their npm package. When the library is installed, Codegen automatically detects the specifications and generates bridging code for the current platform. This is especially important for native libraries, as library users don't need to understand C++, Objective-C, or Java — they just import TypeScript types and use the ready-made components.
Codegen generates files for three target environments: C++ (JSI), Objective-C (iOS), and Java (Android). Each file has a strictly defined role and structure. Understanding what files are created helps with debugging and, if necessary, manual adjustment of the generated code.
For each native module, Codegen creates two C++ files: a header (.h) with the Host Object class declaration and an implementation file (.cpp) with methods that call the corresponding platform functions. The header file contains a class inherited from jsi::HostObject with an overridden get method for accessing module functions. The implementation file contains lambda functions that, when called from JS, delegate execution to the native module.
For iOS, Codegen generates an Objective-C protocol and a category. The protocol declares methods that must be implemented by the native module. The category on RCTCxxBridge contains bridging code that registers the module in RCTTurboModuleManager. This allows calling Objective-C module methods from C++ JSI through the standard RCTBridge mechanism.
For Android, Codegen generates a Java interface and an abstract class. The interface contains method declarations with correct Java types. The abstract class implements the TurboModule interface and contains basic logic for registering the module in ReactPackage. The developer inherits from this class and only implements the business logic of the methods.
// Directory structure after Codegen run
build/
generated/
ios/
NativeCalculatorSpec.h // Objective-C protocol
NativeCalculatorSpec.mm // JSI implementation
android/
NativeCalculatorSpec.java // Java interface
NativeCalculatorModuleBase.java // Base class
cxx/
NativeCalculator.h // C++ Host Object header
NativeCalculator.cpp // C++ JSI implementation
This entire structure is created automatically during project build. Developers should not edit the generated files — they will be overwritten on the next build. If module behavior needs to be changed, modifications are made only to the native implementation source code (Java/Objective-C) or to the TypeScript specification.
Let's walk through the full Codegen workflow by creating a native module for storing data in Keychain. This is a typical task that requires access to the native iOS and Android API.
The developer creates a specification file describing the KeychainStorage module interface. The save and read methods accept a string and return a Promise, since working with Keychain may be asynchronous on some platforms.
import { TurboModule, TurboModuleRegistry } from 'react-native'
export interface KeychainStorageSpec extends TurboModule {
save(key: string, value: string): Promise<void>
read(key: string): Promise<string | null>
delete(key: string): Promise<boolean>
}
export default TurboModuleRegistry.<KeychainStorageSpec>('KeychainStorage')
Codegen runs automatically when building a React Native project. If you need to run it manually, use the npx react-native codegen command. Codegen parses the specification and creates all necessary files in build/generated/. The developer sees the generated C++, Objective-C, and Java files but should not edit them.
# Run Codegen manually
npx react-native codegen --target-path ./build/generated
# After generation — build the project
npx react-native run-ios
npx react-native run-android
After generation and build, the developer imports the module as a regular TypeScript type. The IDE automatically suggests method signatures thanks to the generated .d.ts files. TypeScript guarantees that parameter and return types match the native implementation — if the specification specifies string, the native side will receive exactly a string.
import KeychainStorage from './NativeKeychainStorage'
async function storeToken(token: string) {
await KeychainStorage.save('auth_token', token)
}
async function getToken(): Promise<string | null> {
return KeychainStorage.read('auth_token')
}
This example shows that the JS code contains no platform-specific instructions — it is the same for iOS and Android. All platform-specific details are hidden inside the Codegen-generated code. Codegen handles all the routine work of creating bridges, leaving the developer only business logic and type checking through TypeScript.
Frequently Asked Questions
Usually not — Codegen runs automatically when building a React Native project through Metro and CocoaPods. For manual execution, use the npx react-native codegen command, which is useful for debugging or in CI/CD pipelines for pre-generation.
Yes, Codegen supports primitive types (number, string, boolean), objects with typed fields, arrays, Promise, and Callback. Custom types are defined through TypeScript interface — Codegen will generate the corresponding C++ structures and Java classes.
On the next build, Codegen regenerates all files from scratch. Generated files should not be edited manually — they are read-only. Changes are made exclusively to the TypeScript specification and the native module implementation.
Technically yes, but it wouldn't make sense. Codegen is specifically designed for generating JSI-compatible wrappers that only work with the new architecture (Fabric and TurboModules). For the old Bridge architecture, generation is not needed — Codegen is a tool exclusively for the new architecture.
Codegen supports two specification formats: TypeScript (preferred) and Flow. TypeScript is recommended as it has broader tool support and better integration with IDEs. Flow is supported for backward compatibility with existing Facebook projects.
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also