A collection of Expo brownfield apps
- AntennaPod: Integrated project using monorepo approach
- BlankAndroid: Integrated project using monorepo approach
- NewPipe: Isolated approach using AAR (SDK 56 canary) — Kotlin/Java media client, first user of
expo-brownfield build:android --fused(PR #45878) which bundles every autolinked Expo module + heavy transitives into a single AAR (recording)
- wikipedia-ios: Isolated approach using XCFramework
- simplenote-react-native: Integrated project using monorepo approach
- NetNewsWire: Integrated project using monorepo approach
- BlankIOS: Integrated project using monorepo approach
- ish: Isolated approach using local Swift Package — Objective-C host with a C/asm core (recording)
- KeePassium: Isolated approach using local Swift Package — UIKit password manager with bidirectional shared state (
useSharedState↔BrownfieldState) + native↔RN messaging (recording) - OsmAnd-iOS: Isolated approach using local Swift Package (SDK 57 canary) — ObjC++ map app with bidirectional shared map state (recording)
- firefox-ios: Isolated approach using local Swift Package (SDK 56 canary) — UIKit browser with a Bookmarks Inspector RN screen wired through Firefox's custom
Fennecbuild configurations + Swift 6 strict concurrency (recording) - Signal-iOS: Isolated approach using local Swift Package (SDK 56 canary) — UIKit messenger demonstrating the Navigation API (
popToNative()from JS +setNativeBackEnabled) with a Safety Center RN screen +expo-imageavatars viahostProvidedFrameworks(SDWebImage shared with the host's CocoaPods runtime) (recording) - Nextcloud-iOS: Isolated approach using local Swift Package (SDK 56 canary) — UIKit cloud-files client with a Files Quick Look RN screen (storage quota bar + shared-file indicators), Navigation API + DCO-signed commits (recording)
- pocket-casts-ios: Isolated approach using local Swift Package (SDK 56 canary) — UIKit podcast app demonstrating the
ExpoAppDelegateSubscriberManagerlifecycle pipeline (host AppDelegate forwards everyUIApplicationDelegateevent into anExpoAppDelegateSubscriberthat records toBrownfieldState; live event feed rendered in the RN Lifecycle Trace screen) (recording)
- IceCubesApp: Integrated project using monorepo approach
- yattee: Isolated approach using local Swift Package — SwiftUI YouTube player (recording)
- wallabag-ios: Isolated approach using local Swift Package (SDK 56 canary with the
expo-imageSPM-deps fix) — SwiftUI read-it-later app with a bidirectional reading-list inspector (recording) - element-x-ios: Isolated approach using local Swift Package (SDK 56 canary) — SwiftUI Matrix client built on Element X's
AppCoordinator/ WindowGroup architecture, with a React Native Safety Dashboard presented on a dedicatedUIWindowoverlay (.alert + 1) so it floats over the SwiftUI scene without fighting the host's view-swap flow; bidirectional shared state (encrypted-sessions, verified-devices, recent-rooms feed),BrownfieldMessaging(OPEN_ROOM/VERIFY_KEYS), Navigation API (popToNative()), andexpo-imageavatars (recording)
Check commits inside each repo for detailed steps, full instructions can be found in the expo-brownfield documentation.
-
Set up a yarn monorepo: Create a
package.jsonfile in the root directory, then add the following to it:{ "private": true, "workspaces": ["exp"] } -
Create the Expo app: Run
npx create-expo-app expto set up a new Expo app. -
Install dependencies: Add expo to you Podfile and run
pod install -
Add React Native view: Create a new Swift file in the
NetNewsWire-iOStarget, for exampleReactNativeView.swift, and implement a basic React Native view.
-
Create the Expo app: Run
npx create-expo-app expto set up a new Expo app. -
Install expo-brownfield: Add expo-brownfield to your project
npx expo install expo-brownfieldand generate a XCFramework. -
Add React Native view: Integrate the Expo app XCFramework into the existing iOS app.