Skill

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.

Works with exporeact nativegradlecocoapodsxcode

71
Spark score
out of 100
Updated 21 days ago
Version 1.0.0

Add to Favorites

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

01

Generate AAR/XCFramework builds for isolated consumption by native teams without Node toolchain

02

Configure Gradle and CocoaPods to integrate React Native sources directly into existing native builds

03

Set up ReactNativeViewController, BrownfieldActivity, or RCTRootView components for embedding

04

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.