Install any skill in seconds. Free to start, no credit card required.
Get Started Free →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.
.claude/skills/sediman-agent-expo-brownfield/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | -38% | 0% |
| case-02 | ✗→✓ | ▲ Improved | -20% | 0% |
| case-03 | ✗→✓ | ▲ Improved | -41% | 0% |
| case-04 | ✗→✓ | ▲ Improved | -38% | 0% |
| case-09 | ✗→✓ | ▲ Improved | -45% | 0% |
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.
Use these quick rules — fall through to comparison.md for anything ambiguous.
More information available at https://docs.expo.dev/brownfield/overview/
Both approaches require, in the environment that _builds_ the React Native side:
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.
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:
shnpx create-expo-app@latest my-project --template default@sdk-55
Pin the same Expo SDK across both the RN project and any embedded dependencies.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 21,455 | 8,731 | -59% | 1 | 1 | 0% | 3,468 | 2,166 | -38% | 0 | 0 | — |
case-02 | fail→pass | 15,283 | 7,132 | -53% | 1 | 1 | 0% | 2,586 | 2,064 | -20% | 0 | 0 | — |
case-03 | fail→pass | 21,734 | 8,376 | -61% | 1 | 1 | 0% | 3,627 | 2,154 | -41% | 0 | 0 | — |
case-04 | fail→pass | 11,452 | 3,612 | -68% | 1 | 1 | 0% | 2,142 | 1,319 | -38% | 0 | 0 | — |
case-05 | pass→pass | 11,428 | 5,219 | -54% | 1 | 1 | 0% | 1,946 | 1,641 | -16% | 0 | 0 | — |
case-06 | pass→pass | 15,631 | 4,465 | -71% | 1 | 1 | 0% | 2,506 | 1,413 | -44% | 0 | 0 | — |
case-07 | pass→pass | 14,730 | 6,061 | -59% | 1 | 1 | 0% | 2,430 | 1,778 | -27% | 0 | 0 | — |
case-08 | pass→pass | 5,661 | 2,233 | -61% | 1 | 1 | 0% | 1,018 | 1,062 | +4% | 0 | 0 | — |
case-09 | fail→pass | 18,713 | 5,459 | -71% | 1 | 1 | 0% | 2,951 | 1,637 | -45% | 0 | 0 | — |
case-10 | fail→pass | 12,905 | 3,731 | -71% | 1 | 1 | 0% | 2,230 | 1,360 | -39% | 0 | 0 | — |
case-11 | fail→pass | 16,303 | 6,725 | -59% | 1 | 1 | 0% | 2,804 | 1,942 | -31% | 0 | 0 | — |
case-12 | pass→pass | 11,161 | 4,733 | -58% | 1 | 1 | 0% | 1,857 | 1,538 | -17% | 0 | 0 | — |
case-13 | pass→pass | 8,271 | 2,543 | -69% | 1 | 1 | 0% | 1,286 | 1,169 | -9% | 0 | 0 | — |
case-14 | pass→pass | 13,927 | 5,086 | -63% | 1 | 1 | 0% | 2,224 | 1,547 | -30% | 0 | 0 | — |
case-15 | fail→pass | 15,842 | 5,463 | -66% | 1 | 1 | 0% | 2,527 | 1,560 | -38% | 0 | 0 | — |
case-16 | pass→pass | 9,038 | 3,144 | -65% | 1 | 1 | 0% | 1,547 | 1,152 | -26% | 0 | 0 | — |
case-17 | pass→pass | 11,019 | 5,250 | -52% | 1 | 1 | 0% | 1,784 | 1,589 | -11% | 0 | 0 | — |
case-18 | fail→pass | 11,786 | 1,719 | -85% | 1 | 1 | 0% | 2,091 | 1,049 | -50% | 0 | 0 | — |
case-19 | fail→pass | 18,817 | 2,872 | -85% | 1 | 1 | 0% | 2,940 | 1,258 | -57% | 0 | 0 | — |
case-20 | fail→pass | 13,323 | 9,915 | -26% | 1 | 1 | 0% | 2,371 | 2,506 | +6% | 0 | 0 | — |
case-21 | fail→fail | 15,789 | 10,665 | -32% | 1 | 1 | 0% | 2,773 | 2,795 | +1% | 0 | 0 | — |
case-22 | fail→fail | 18,701 | 13,948 | -25% | 1 | 1 | 0% | 3,528 | 3,428 | -3% | 0 | 0 | — |
case-23 | fail→fail | 8,038 | 6,397 | -20% | 1 | 1 | 0% | 1,529 | 1,868 | +22% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted. The headline lift of +48 percentage points is the difference between those two pass rates over the 23 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.