CodegenはReact Nativeエコシステムにおける自動コード生成ツールであり、ネイティブモジュールインターフェースの宣言的仕様に基づいてTypeScript、C++、Objective-Cのラッパーを作成します。開発者はJavaScriptファイルでメソッドシグネチャとパラメータタイプのみを記述し、CodegenがJSとネイティブ側の間のすべてのブリッジコードを生成します。React Native Documentation (2025)によると、Codegenは定型コードを自動化することで、ネイティブモジュールの開発時間を平均60%削減します。
重要ポイント
Codegen(Code Generatorの略)はReact Nativeに含まれるコマンドラインユーティリティで、JavaScriptとネイティブプラットフォーム(iOS、Android)間の連携のためのブリッジコードを自動生成します。Codegenは新しいReact Nativeアーキテクチャの不可欠な部分であり、Fabric(レンダラー)とTurboModules(ネイティブモジュール)の両方に使用されます。
Codegenの主な考え方は責務の分離です。開発者は関数が「何を」すべきか(そのシグネチャ)を記述し、Codegenがそれをネイティブ側に「どのように」渡すかを生成します。これにより、JSI用のC++ラッパー、iOS用のObjective-Cスタブ、Android用のJavaクラスを手動で記述する必要がなくなります。単一の真実源(TypeScript仕様)により、すべてのレベルで型が一致することが保証され、JSとネイティブコード間の型の不一致に関連するエラーの全クラスが排除されます。
Codegenは新しいReact Nativeアーキテクチャ(0.70+)の最初の安定版とともに導入され、それ以来ネイティブモジュール作成の必須ツールとなっています。Codegenがない場合、開発者はJSI Host Objectsを手動で記述する必要があり、C++の深い知識とJavaScriptエンジンの内部構造の理解が要求されます。
Codegen以前は、React Native用のネイティブモジュール開発には3つのステップが必要でした。JavaScriptインターフェースの作成、Java/Objective-Cでのネイティブモジュールの実装、そして手動でのブリッジ作成です。メソッドのシグネチャが変更されると、3つのファイルすべてを同期的に更新する必要がありました。Codegenはこのルーチンを自動化し、変更はTypeScript仕様にのみ加えられ、他のすべては再生成されます。
CodegenはMetroとCocoaPodsを介してReact Nativeのビルドプロセスに統合されます。ビルドを開始すると、CodegenはTypeScript仕様を解析し、C++およびプラットフォームファイルを生成してビルドディレクトリに配置します。つまり、生成されたコードは常に現在の仕様と一致し、手動での更新は不要です。
Codegenのワークフローは3つの段階で構成されます。仕様の解析、中間表現の構築、ターゲットファイルの生成です。各段階は分離されており、新しいプラットフォームや生成言語のサポートを容易に追加できます。
最初の段階では、CodegenはTypeScriptまたはFlow形式の仕様ファイルを読み取ります。仕様はネイティブモジュールインターフェース(メソッド名、パラメータタイプ、戻り値の型)を記述します。Codegenはプリミティブ型(number、string、boolean)だけでなく、オブジェクト、配列、Promise、Callbackなどの複雑な型もサポートします。仕様はプロジェクトの特別なディレクトリにある.tsまたは.jsファイルに保存されます。
2番目の段階では、Codegenは解析された仕様から抽象構文木(AST)を構築します。ASTはデータ構造を特定の生成言語に依存しないニュートラルな形式で表現します。これにより、単一のASTからFabric用のC++コード、iOS用のObjective-C、Android用のJavaを生成でき、すべてのプラットフォームをサポートするために追加の作業は不要です。
3番目の段階では、Codegenはテンプレートエンジン(Mustacheベース)を使用してターゲットプラットフォームのファイルを生成します。各テンプレートは特定のファイルタイプ(C++ヘッダー(.h)、実装(.cpp)、Objective-Cプロトコル(.h)または実装(.mm)、Javaクラス)を処理します。テンプレートはReact Nativeに付属していますが、プロジェクトの特定のニーズに合わせてカスタマイズできます。
// 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')
この例では、仕様はaddとmultiplyの2つのメソッドを持つNativeCalculatorモジュールを記述しています。どちらもDoubleを受け取りDoubleを返します。TurboModuleRegistryの文字列「NativeCalculator」は、ネイティブ側で使用されるモジュール名を指定します。Codegenはこの仕様に基づいて、FabricとTurboModulesに必要なすべてのファイルを生成します。
Fabric(新しいReact Nativeレンダラー)のコンテキストでは、Codegenは特別な役割を果たします。Fabricでは、すべてのネイティブUIコンポーネントがJSIを通じて作成および管理できるC++表現を持つ必要があります。Codegenはコンポーネント仕様に基づいてこれらのC++表現を自動的に生成します。
UIコンポーネントの場合、CodegenはC++ Shadow Nodeクラスだけでなく、プラットフォーム固有の表現も生成します。たとえば、iOS上のカスタムButtonコンポーネントの場合、CodegenはコンポーネントをFabricに登録し、C++ Shadow NodeにリンクするObjective-Cクラスを作成します。開発者はTypeScript仕様でコンポーネントのプロパティ(色、サイズ、ハンドラー)を記述するだけで済みます。
Codegenは直接および逆方向のデータ転送の両方をサポートします。直接イベント(onPressなど)は、JSに渡されるときに自動的にシリアライズされるフィールドを持つC++構造体として生成されます。EventEmitterを使用すると、ネイティブ側はJSからの要求なしにJSにイベントを送信できます。Codegenは両方向に対して型付けされたラッパーを生成し、フィールド名の不一致エラーを排除します。
| コンポーネント | 仕様(TypeScript) | C++生成 | プラットフォーム生成 |
|---|---|---|---|
| メソッド | add(a: Double): Double | JSI Host関数 | iOS/AndroidのNativeMethod |
| プロパティ | color: String | Shadow Nodeプロパティ | UIView/Viewプロパティ |
| イベント | onPress: () => Void | Event構造体 | UIControl/Viewコールバック |
| 定数 | PI: Double | Const getter | 定数エクスポート |
ライブラリ開発者は、npmパッケージにCodegen仕様を含めることができます。ライブラリをインストールすると、Codegenは自動的に仕様を検出し、現在のプラットフォーム用のブリッジコードを生成します。これはネイティブライブラリにとって特に重要です。ライブラリのユーザーはC++、Objective-C、Javaを理解する必要がなく、TypeScript型をインポートして既製のコンポーネントを使用するだけです。
Codegenは3つのターゲット環境向けにファイルを生成します。C++(JSI)、Objective-C(iOS)、Java(Android)です。各ファイルには厳密に定義された役割と構造があります。どのファイルが作成されるかを理解することは、デバッグや、必要に応じて生成コードの手動調整に役立ちます。
各ネイティブモジュールに対して、Codegenは2つのC++ファイルを作成します。Host Objectクラス宣言を含むヘッダーファイル(.h)と、プラットフォーム上の対応する関数を呼び出すメソッドを含む実装ファイル(.cpp)です。ヘッダーファイルにはjsi::HostObjectから継承したクラスが含まれ、モジュールの関数にアクセスするためのオーバーライドされたgetメソッドを持ちます。実装ファイルには、JSから呼び出されたときにネイティブモジュールに実行を委譲するラムダ関数が含まれます。
iOSの場合、CodegenはObjective-Cプロトコルとカテゴリを生成します。プロトコルはネイティブモジュールが実装すべきメソッドを宣言します。RCTCxxBridgeのカテゴリには、モジュールをRCTTurboModuleManagerに登録するブリッジコードが含まれます。これにより、標準のRCTBridgeメカニズムを通じてC++ JSIからObjective-Cモジュールメソッドを呼び出すことができます。
Androidの場合、CodegenはJavaインターフェースと抽象クラスを生成します。インターフェースには正しいJava型を持つメソッド宣言が含まれます。抽象クラスはTurboModuleインターフェースを実装し、モジュールをReactPackageに登録するための基本ロジックを含みます。開発者はこのクラスを継承し、メソッドのビジネスロジックのみを実装します。
// 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
この構造全体はプロジェクトのビルド中に自動的に作成されます。開発者は生成されたファイルを編集すべきではありません。次のビルドで上書きされます。モジュールの動作を変更する必要がある場合は、ネイティブ実装のソースコード(Java/Objective-C)またはTypeScript仕様のみに変更が加えられます。
Keychainにデータを保存するためのネイティブモジュールを作成して、Codegenの完全なワークフローを見てみましょう。これはiOSとAndroidのネイティブAPIへのアクセスを必要とする典型的なタスクです。
開発者はKeychainStorageモジュールインターフェースを記述する仕様ファイルを作成します。saveメソッドとreadメソッドは文字列を受け取りPromiseを返します。Keychainの操作は一部のプラットフォームで非同期になる可能性があるためです。
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はReact Nativeプロジェクトのビルド時に自動的に実行されます。手動で実行する必要がある場合は、npx react-native codegenコマンドを使用します。Codegenは仕様を解析し、build/generated/に必要なすべてのファイルを作成します。開発者は生成されたC++、Objective-C、Javaファイルを確認できますが、編集はしないでください。
# 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
生成とビルドの後、開発者はモジュールを通常のTypeScript型としてインポートします。生成された.d.tsファイルのおかげで、IDEは自動的にメソッドシグネチャを提案します。TypeScriptはパラメータと戻り値の型がネイティブ実装と一致することを保証します。仕様が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')
}
この例では、JSコードにプラットフォーム固有の指示が含まれていないことがわかります。iOSとAndroidで同じです。すべてのプラットフォーム固有の詳細はCodegenが生成したコード内に隠されています。Codegenはブリッジ作成のすべてのルーチン作業を処理し、開発者にはビジネスロジックとTypeScriptによる型チェックのみが残されます。
よくある質問
通常は不要です。CodegenはMetroとCocoaPodsを通じてReact Nativeプロジェクトのビルド時に自動的に実行されます。手動実行にはnpx react-native codegenコマンドを使用します。これはデバッグやCI/CDパイプラインでの事前生成に便利です。
はい、Codegenはプリミティブ型(number、string、boolean)、型付けされたフィールドを持つオブジェクト、配列、Promise、Callbackをサポートしています。カスタム型はTypeScript interfaceで定義され、Codegenが対応するC++構造体とJavaクラスを生成します。
次のビルドで、Codegenはすべてのファイルを最初から再生成します。生成されたファイルは手動で編集しないでください。これらは読み取り専用です。変更はTypeScript仕様とネイティブモジュールの実装のみに行われます。
技術的には可能ですが、意味がありません。Codegenは新しいアーキテクチャ(FabricおよびTurboModules)でのみ動作するJSI互換ラッパーを生成するために特別に設計されています。古いBridgeアーキテクチャでは生成は不要です。Codegenは新しいアーキテクチャ専用のツールです。
CodegenはTypeScript(推奨)とFlowの2つの仕様形式をサポートしています。TypeScriptはツールサポートがより広く、IDEとの統合が優れているため推奨されます。Flowは既存のFacebookプロジェクトとの後方互換性のためにサポートされています。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。