Integrate Expo and React Native into existing native apps
A skill for integrating Expo/React Native into an existing native iOS or Android app via isolated or integrated approaches.
Why it matters
Add React Native and Expo capabilities to an existing iOS or Android native application through either an isolated prebuilt library approach or an integrated source-based approach, enabling incremental adoption without rewriting the entire app.
Outcomes
What it gets done
Generate AAR/XCFramework builds for isolated consumption by native teams without Node toolchain
Configure Gradle and CocoaPods to integrate React Native sources directly into existing native builds
Set up ReactNativeViewController, BrownfieldActivity, or RCTRootView components for embedding
Troubleshoot Metro connection, module resolution, and build signing issues across brownfield scenarios
Install
Add it to your toolbox
Run in your project directory:
curl -fsSL https://spark.entire.vc/get/ag-expo-brownfield | bash Overview
Expo Brownfield
This skill guides integrating Expo and React Native into an existing native iOS or Android app, choosing between an isolated AAR/XCFramework approach and an integrated Gradle/CocoaPods build. Use it when embedding React Native into an existing native app or troubleshooting brownfield-specific build issues. Requires Expo SDK 55 or later.
What it does
This skill guides integrating Expo and React Native into an existing native iOS or Android app - a brownfield app that adopts React Native incrementally, as opposed to a greenfield app that is React Native from day one. It distinguishes two distinct approaches Expo supports for brownfield integration. The isolated approach ships a prebuilt AAR or XCFramework to the native app, letting the native team consume React Native as a regular library dependency without installing Node, Yarn, or any React Native build toolchain, and suits teams where RN code and native code live in separate repositories or release on independent cadences. The integrated approach instead adds React Native sources directly into the existing Gradle and CocoaPods build, suiting a single team that owns both the native and RN code, is comfortable with RN tooling, and wants hot reload and JS source maps working seamlessly inside the existing native build process rather than a separate build pipeline.
Quick selection rules point toward isolated when the iOS or Android team must consume RN as a library dependency without installing the RN toolchain, or when RN and native code are versioned and released independently, and point toward integrated when one team owns everything and wants a single unified build with working hot reload. For anything ambiguous, a full decision matrix with detailed trade-offs and scenario mapping lives in a dedicated comparison reference. Further references cover building RN as an AAR or XCFramework and consuming it via BrownfieldActivity, ReactNativeViewController, or ReactNativeView for the isolated path; adding RN and Expo directly to existing Gradle and CocoaPods builds via ReactActivity, RCTRootView, and Podfile for the integrated path; and a troubleshooting reference covering Metro connection, build, signing, and module-resolution issues common to both approaches.
Both approaches require Node.js LTS to run the Expo CLI and JavaScript code, and Yarn to manage JavaScript dependencies, in whichever environment builds the React Native side. The integrated approach additionally requires CocoaPods on iOS, while the isolated approach requires no CocoaPods or RN tooling at all in the consuming native app. Expo SDK 55 is the minimum supported version for brownfield integration, since earlier SDKs lack the expo-brownfield package, the required ExpoReactHostFactory and ExpoReactNativeFactory entry points, and the current autolinking surface - so the Expo project must be created with the SDK explicitly pinned to that version, and the same Expo SDK version must be pinned consistently across both the RN project and any embedded dependencies.
When to use - and when NOT to
Use it when embedding React Native in an existing native iOS or Android app, choosing between AAR/XCFramework and integrated Gradle/CocoaPods approaches, or troubleshooting brownfield-specific build and Metro connection issues. Not for greenfield apps that are React Native from the start.
Inputs and outputs
Given an existing native iOS or Android codebase, it produces a chosen integration approach - isolated AAR/XCFramework or integrated Gradle/CocoaPods build - along with the specific setup steps, prerequisites, and SDK version pin required for that path.
Integrations
Gradle and CocoaPods native build systems, the Expo CLI, Node.js and Yarn, and Expo SDK 55's expo-brownfield package with its ExpoReactHostFactory and ExpoReactNativeFactory entry points.
Who it's for
Native iOS and Android teams incrementally adopting React Native inside an existing app, who need to choose and correctly set up either an isolated library-consumption approach or a fully integrated build.
Source README
Expo Brownfield
When to Use
Use this skill when you need integrate Expo and React Native into an existing native iOS or Android app. Use when the user mentions brownfield, embedding React Native in a native app, AAR/XCFramework, or adding Expo to an existing Kotlin/Swift project. Covers both the isolated approach and the integrated approach.
A brownfield app is an existing native iOS or Android app that adopts React Native incrementally, as opposed to a greenfield app that is React Native from day one.
Expo supports two distinct ways to add React Native to a brownfield project:
| Approach | What ships to the native app | When to choose |
|---|---|---|
| Isolated | Prebuilt AAR / XCFramework | Native team doesn't need Node or RN tooling; RN code can live in a separate repo |
| Integrated | React Native sources added to the existing Gradle / CocoaPods build | One team owns everything; comfortable with RN tooling; wants a single build |
For the full decision matrix, see ./references/comparison.md.
Pick an approach
Use these quick rules - fall through to comparison.md for anything ambiguous.
- Choose isolated if the iOS/Android team must consume RN as a regular library dependency (AAR or XCFramework), without installing Node, Yarn, or the React Native build toolchain.
- Choose isolated if RN code and native code live in separate repositories or release on independent cadences.
- Choose integrated if a single team owns both the native and RN code and is willing to add React Native + Expo to the native project's Gradle and CocoaPods setup.
- Choose integrated if you want hot reload and JS source maps to work seamlessly inside the existing native build process.
References
- ./references/brownfield-isolated.md -- Build RN as AAR/XCFramework and consume from the native app (BrownfieldActivity, ReactNativeViewController, ReactNativeView)
- ./references/brownfield-integrated.md -- Add RN and Expo directly to existing Gradle and CocoaPods builds (ReactActivity, RCTRootView, Podfile)
- ./references/comparison.md -- Decision criteria, trade-offs, and scenario mapping for choosing an approach
- ./references/troubleshooting.md -- Metro connection, build, signing, and module-resolution issues common to both approaches
More information available at https://docs.expo.dev/brownfield/overview/
Shared prerequisites
Both approaches require, in the environment that builds the React Native side:
- Node.js (LTS) - runs the Expo CLI and JavaScript code.
- Yarn - manages JavaScript dependencies.
The integrated approach additionally requires CocoaPods on iOS (sudo gem install cocoapods). The isolated approach does not require CocoaPods or any RN tooling in the consuming native app.
Versioning note
Expo SDK 55 is the minimum supported version for brownfield integration. Earlier SDKs lack expo-brownfield, the required ExpoReactHostFactory / ExpoReactNativeFactory entry points, and the current autolinking surface. When creating the Expo project, always pin the SDK explicitly:
npx create-expo-app@latest my-project --template default@sdk-55
Pin the same Expo SDK across both the RN project and any embedded dependencies.
Limitations
- Use this skill only when the task clearly matches its upstream product or API scope.
- Verify commands, API behavior, pricing, quotas, credentials, and deployment effects against current official documentation before making changes.
- Do not treat generated examples as a substitute for environment-specific tests, security review, or user approval for destructive or costly actions.
FAQ
Common questions
Discussion
Questions & comments · 0
Sign In Sign in to leave a comment.