expo-brownfield について
expo-brownfield は、既存の iOS または Android ネイティブアプリに React Native 機能を段階的に追加するチーム向けのスキルです。成果物を分離する方法とビルドを統合する方法、互換性確認、ホストアプリでの検証を説明します。
主な機能
- 01分離型と統合型の方式
- 02Brownfield 導入方式の選定指針
- 03バージョン互換性の確認
- 04ネイティブホストへの統合指針
- 05リリース検証シナリオ
活用シーン
- 01ネイティブアプリへの React Native 画面の組み込み
- 02ネイティブコードと RN コードのビルド方式の選択
- 03リリースビルドでの統合機能の確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ expo/ skills --skill expo-brownfieldインストール後、Claude Code で/expo-brownfieldを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
agents/openai.yamlreferences/brownfield-integrated.mdbrownfield-isolated.mdcomparison.mdfeature-integration.mdtroubleshooting.mdversion-compatibility.md詳細
Expo のブラウンフィールド開発
ブラウンフィールドアプリとは、React Native を最初から採用しているグリーンフィールドアプリとは異なり、既存のネイティブ iOS または Android アプリに React Native を段階的に導入したアプリです。
まずホストアプリを確認する
既存アプリのエントリーポイント、ナビゲーションの管理元、ネイティブのビルドシステム、デプロイ対象、すでにリンクされている React Native ランタイムを特定します。ロックファイルから、インストール済みの Expo、React Native、ブラウンフィールド用パッケージのバージョンを記録します。Swift アプリに EAS Build または Submit を追加するだけであれば、React Native は必要ありません。そのタスクは eas-app-stores に振り分けてください。
機能を組み込む際は、ホストアプリの SwiftUI App/UIKit ウィンドウとネイティブ画面を維持してください。**手動で管理しているネイティブホストでは、トラブルシューティング中も含め、prebuild を実行しないでください。**分離された Expo プロデューサーでは CNG を使用できます。生成された ios/ と android/ は、アプリに組み込む側とは分けておいてください。
Expo では、ブラウンフィールドプロジェクトに React Native を追加する方法が 2 つあります。
| アプローチ | ネイティブアプリに組み込むもの | 選択する状況 |
|---|---|---|
| 分離型 | 事前ビルド済みの AAR/XCFramework | ネイティブチームが Node や RN のツールを必要としない場合、RN コードを別のリポジトリに置ける場合 |
| 統合型 | 既存の Gradle/CocoaPods ビルドに追加した React Native ソース | すべてを 1 つのチームが担当し、RN のツールに慣れていて、単一のビルドを希望する場合 |
詳しい判断基準については、./references/comparison.md を参照してください。
アプローチを選ぶ
以下の簡単な基準を使い、判断が難しい場合は comparison.md を参照してください。
- iOS/Android チームが Node、Yarn、React Native のビルドツールチェーンをインストールせずに、通常のライブラリ依存関係(AAR または XCFramework)として RN を利用する必要がある場合は、分離型を選びます。
- RN コードとネイティブコードが別々のリポジトリにある場合、またはそれぞれ独立したリリースサイクルでリリースする場合は、分離型を選びます。
- 1 つのチームがネイティブコードと RN コードの両方を担当し、ネイティブプロジェクトの Gradle と CocoaPods の設定に React Native と Expo を追加してもよい場合は、統合型を選びます。
- どちらのアプローチも、Debug で Metro と Fast Refresh を利用できます。分離型では JS のライブ反復ができないからではなく、ビルドを一元管理するために統合型を選んでください。
参考資料
- ./references/brownfield-isolated.md -- RN を AAR/XCFramework としてビルドし、ネイティブアプリに組み込む(BrownfieldActivity、ReactNativeViewController、ReactNativeView)
- ./references/brownfield-integrated.md -- RN と Expo を既存の Gradle および CocoaPods ビルドに直接追加し、ネイティブアプリのシェルを維持する
- ./references/feature-integration.md -- 入力の受け渡し、結果の返却、画面の終了、リスナーのクリーンアップ、ライフサイクルイベントの転送。SwiftUI ホストの例を含みます
- ./references/comparison.md -- アプローチを選択するための判断基準、トレードオフ、シナリオの対応関係
- ./references/troubleshooting.md -- どちらのアプローチにも共通する Metro 接続、ビルド、署名、モジュール解決の問題
詳細は https://docs.expo.dev/brownfield/overview/ をご覧ください。
共通の前提条件
どちらのアプローチでも、React Native 側を ビルドする 環境に次のものが必要です。
- Node.js(LTS) — Expo CLI と JavaScript コードを実行します。
- プロジェクトのパッケージマネージャーとロックファイル — npm、Yarn、pnpm、または Bun。例に合わせるためだけにパッケージマネージャーを切り替えないでください。
iOS のビルド環境には Xcode と CocoaPods が必要です(Gemfile/Bundler の設定がある場合は、プロジェクトの設定を使用してください)。分離型で成果物を利用するアプリは、成果物を利用するだけであれば Xcode が必要ですが、CocoaPods や RN のツールは必要ありません。
互換性のあるバージョンを選択する
既存の Expo/RN プロジェクトでは、選択済みの SDK を維持し、npx expo install を使用して依存関係を整合させてください。このスキルに合わせるためだけにアップグレードしないでください。新しいプロデューサーを作成する場合は、ホストの OS サポート、依存関係、ビルドツールチェーンと互換性のある最新の安定版 SDKを使用してください。選択前に、リリースが安定版であることを確認してください。
ネイティブのセットアップを始める前に、./references/version-compatibility.md を読み、各 SDK バージョンに対応するネイティブテンプレート、ツールチェーンと OS の要件、ビルドのデフォルトを確認してください。ネイティブのみのコンシューマーには固定する Expo SDK バージョンがありませんが、アーティファクトの要件を満たす必要があります。
ホストで機能を検証する
入力を含む RN 画面を開き、結果をネイティブに返してから閉じ、新しい入力で再度開いてください。リスナーのクリーンアップと、ホスト本来のナビゲーションを確認してください。その後、Metro を停止し、Release アーティファクトを使ってホストを Release モードでビルドしてください。Expo Go またはプロデューサーのサンプルアプリでのレンダリングだけでは、統合を検証したことになりません。完全な受け入れシナリオについては、./references/feature-integration.md を参照してください。
フィードバックを送信する
このスキルに関するエラー、誤解を招く情報、古い情報に気づいた場合は、Expo の改善に役立てるため報告してください。
npx --yes @expo/agent-cli@latest feedback --category skills --subject "expo-brownfield" "<actionable feedback>"
具体的で対応可能な内容がある場合にのみ送信してください。関連するコンテキストをできるだけ詳しく含めてください。
エージェントが Expo のタスクを繰り返し失敗する場合や、ユーザーが介入しなければならない場合は、タスクの概要、期待した結果、問題の内容を簡潔に報告し、--category evals と、関連する Expo パッケージまたはコマンドを --subject として指定してください。