new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Expo & React Native · all subjects

brownfield

40 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

Integrated approach for adding Expo to native app

The integrated approach adds React Native and Expo to an existing native app by integrating them as a regular library rather than packaging them as a black box. This allows incremental adoption, one screen or view at a time, without requiring a complete rewrite.

Prerequisites for Expo brownfield integration

Node.js LTS, Yarn, and CocoaPods (for iOS) are required. Node.js and Yarn are needed to run JavaScript code and Expo CLI. CocoaPods is required as a dependency management system for iOS and is installed via Ruby.

Create Expo project command for brownfield

Create an Expo project using: npm: `npx create-expo-app@latest my-project --template default@sdk-57`, yarn: `yarn create expo-app my-project --template default@sdk-57`, pnpm: `pnpm create expo-app my-project --template default@sdk-57`, or bun: `bun create expo my-project --template default@sdk-57`. This creates a new directory with your Expo project including an example TypeScript application.

Project structure for brownfield: android and ios directories

Place native code in android and ios directories at the root of your Expo project. Android projects go in my-project/android and iOS projects go in my-project/ios.

Monorepo setup for custom folder structure

If you cannot move native projects to android and ios directories, set up a Yarn monorepo by creating a package.json at the project root with content: {"version": "1.0.0", "private": true, "workspaces": ["my-project"]}. Then run yarn install. This ensures node_modules are at the root and native scripts can interact with React Native code. Custom project root configuration is required in Gradle/CocoaPods.

Android settings.gradle configuration for Expo

Configure settings.gradle with pluginManagement that loads React Native Gradle Plugin and Expo autolinking plugin. Use exec to resolve paths to @react-native/gradle-plugin and expo-modules-autolinking. Configure extensions with com.facebook.react.ReactSettingsExtension and expo-autolinking. Include plugins: id("com.facebook.react.settings") and id("expo-autolinking-settings"). Call expoAutolinking.useExpoVersionCatalog() and expoAutolinking.useExpoModules().

Android build.gradle top-level configuration

The top-level build.gradle must include plugins and configurations to make React Native Gradle and Expo plugins available and applied to the project.

Android app/build.gradle configuration

The app/build.gradle file must include Expo-specific configuration. If using a custom folder structure, adjust the projectRoot value to point to the root of your Expo project.

Android gradle.properties required settings

Add to gradle.properties: reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64, newArchEnabled=true, hermesEnabled=true.

Android INTERNET permission required

Add the INTERNET permission to AndroidManifest.xml to allow network access.

Android debug manifest cleartext traffic for Metro

Enable cleartext traffic in the debug AndroidManifest.xml to allow the app to communicate with the local Metro bundler via HTTP.

Android MainApplication initialization for React Native

Update your Application class to initialize React Native. Reference the bare minimum template's MainApplication.kt for implementation details.

Android ReactActivity implementation

Create a new Activity extending ReactActivity that hosts React Native code. The activity is responsible for starting the React Native runtime and rendering React components. The getMainComponentName() method should return "main". The createReactActivityDelegate() method should return a ReactActivityDelegate using DefaultReactActivityDelegate wrapped with ReactActivityDelegateWrapper, passing BuildConfig.IS_NEW_ARCHITECTURE_ENABLED and fabricEnabled flags.

Android activity theme configuration

Set the theme of ReactActivity to Theme.AppCompat.Light.NoActionBar or another non-ActionBar theme in AndroidManifest.xml to avoid rendering an ActionBar on top of the React Native screen.

iOS Podfile configuration for Expo

Create or update Podfile with: require expo autolinking and react_native_pods scripts; platform :ios, '16.4'; call prepare_react_native_project!(); use target with use_expo_modules!(); configure react-native-config using expo-modules-autolinking; call use_native_modules!() with config command; call use_react_native!() with path to react-native, hermes_enabled: true, app_path, and privacy_file_aggregation_enabled: true; include post_install hook with react_native_post_install.

iOS pod install command

Run `pod install` after configuring the Podfile to integrate React Native code into the app, allowing iOS files to import React Native headers.

iOS Xcode workspace requirement

After pod install, CocoaPods creates a {Project}.xcworkspace file. Open the xcworkspace rather than the traditional xcodeproj. Use `xed my-project/ios` to open the workspace.

iOS ENABLE_USER_SCRIPT_SANDBOXING build setting

In Xcode Build Settings, search for ENABLE_USER_SCRIPT_SANDBOXING and set its value to No. This is required to properly switch between Debug and Release versions of the Hermes engine shipped with React Native.

iOS Build Phases script for JavaScript bundling

Add a Run Script Phase in Build Phases before [CP] Embed Pods Frameworks. This script sources .xcode.env and .xcode.env.local, sets PROJECT_ROOT (one level up from ios directory), skips bundling in Debug, resolves ENTRY_FILE using expo/scripts/resolveAppEntry, resolves CLI_PATH to Expo CLI, sets BUNDLE_COMMAND to "export:embed" by default, sources .xcode.env.updates and .xcode.env.local for overrides, and runs react-native-xcode.sh. The script bundles JavaScript code and assets into the iOS application.

iOS Info.plist UIViewControllerBasedStatusBarAppearance setting

Add the UIViewControllerBasedStatusBarAppearance key with value NO to Info.plist to ensure the status bar is properly managed by React Native.

iOS ReactViewController implementation

Create ReactViewController.swift extending UIViewController. In viewDidLoad, initialize a ReactNativeDelegate and RCTReactNativeFactory, set the factory delegate's dependencyProvider to RCTAppDependencyProvider(), and set the view using rootViewFactory.view(withModuleName: "HelloWorld"). The ReactNativeDelegate extends RCTDefaultReactNativeFactoryDelegate, overrides sourceURL to call bundleURL(), and overrides bundleURL() to return the Metro entry in Debug using RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: ".expo/.virtual-metro-entry") or the bundled main.jsbundle in Release.

iOS presenting React Native view modally

To present React Native view, create a ViewController with a button that instantiates and presents ReactViewController modally. Use UIButton with an action to present the ReactViewController when tapped.

Starting Metro bundler for brownfield development

Run `npm run start` (npm), `yarn run start` (yarn), `pnpm run start` (pnpm), or `bun run start` (bun) in the React Native directory to start the Metro bundler. Metro builds TypeScript code into a bundle, serves it via HTTP on localhost, and enables hot reloading. JavaScript code loads from the development server when reaching the React-powered Activity.

Metro Bundler setup for brownfield debug builds

To use the app with Metro Bundler in debug mode, run 'yarn start' in the app directory and use artifacts built in 'Debug' or 'All' build types. These build types are only supported for Android.

expo-brownfield build command for Android

To build Android brownfield artifacts as reusable packages, use the command: npx expo-brownfield build:android --repo MavenLocal --all --verbose

expo-brownfield build commands for iOS

To build iOS brownfield artifacts, use either 'npx expo-brownfield build:ios --release --verbose' for release builds or 'npx expo-brownfield build:ios --debug --verbose' for debug builds.

expo-brownfield test app purpose

The brownfield-tester app is used for testing the expo-brownfield package and its integration with other packages like expo-router, expo-updates, and expo-dev-menu. It also serves as the base app for expo-brownfield E2E tests.

isolated directory in Brownfield Tester

The isolated directory contains standalone native Android and iOS apps that consume pre-built brownfield artifacts as Maven packages and xcframeworks. They are fully self-contained and do not depend on the monorepo at build time, making this the recommended distribution approach.

Brownfield Tester App structure and purpose

The Brownfield Tester App is a sample application used to test brownfield integration with Expo modules. It contains three main directories: expo-app, integrated, and isolated.

expo-app directory in Brownfield Tester

The expo-app directory contains the React Native / Expo app that serves as the JavaScript source and brownfield artifact builder.

integrated directory in Brownfield Tester

The integrated directory contains native Android and iOS apps that integrate directly with the monorepo using Expo autolinking. They point their project root to expo-app/ and resolve modules at build time.

Brownfield Tester Integrated uses Expo autolinking

The Brownfield Tester Integrated app integrates directly with the Expo monorepo using Expo autolinking. It points its build and project root to ../expo-app, which means React Native modules are resolved and linked at build time from the monorepo's node_modules.

Brownfield Tester Integrated project setup is invalid and should not be replicated

The Brownfield Tester Integrated app redirects its build and project root to ../expo-app. This is an invalid project setup that should not be replicated to other tests or E2E setups and needs to be refactored.

Android Brownfield Tester initialization and Java 17 configuration

The Android app was initialized by creating a new Empty Activity project in Android Studio 2025.1.3 and following the Brownfield Integration guide to integrate Expo modules. Due to React Native targeting Java 17, the default compileOptions were removed from app/build.gradle.kts and dependencyResolutionManagement repositoriesMode was removed from settings.gradle.kts because the react-native plugin configures the maven repo.

iOS Brownfield Tester initialization and Swift 6 configuration

The iOS app was initialized by creating a new SwiftUI project in Xcode 26 and following the Brownfield Integration guide to integrate Expo modules. Due to Swift 6 not being totally supported yet, it was necessary to set Default Actor isolation to nonisolated in the project settings.

Brownfield isolated apps use pre-built artifacts, not Expo autolinking

Brownfield isolated tester apps consume pre-built brownfield artifacts (Maven local repository for Android, xcframeworks via Swift Package for iOS). They do not use Expo autolinking or depend on the monorepo's node_modules at build time — they are fully self-contained. This is the recommended approach for distributing brownfield integrations to existing native apps.

Generate brownfield artifacts for Android with Maven Local

To build Android brownfield artifacts, run: npx expo prebuild --clean -p android, then npx expo-brownfield build:android --repo MavenLocal --all --verbose. This builds and publishes to MavenLocal.

Generate brownfield artifacts for iOS with xcframeworks

To build iOS brownfield artifacts, run: npx expo prebuild --clean -p ios, then npx expo-brownfield build:ios --release --verbose and npx expo-brownfield build:ios --debug --verbose. This builds xcframeworks.

Android brownfield app resolves libraries from mavenLocal()

Once artifacts are published to Maven Local, open the android/ project in Android Studio and build normally. The app resolves the brownfield libraries from mavenLocal().

iOS brownfield app uses xcframeworks via Swift Package

After building xcframeworks, the add_xcframeworks.rb script (in the E2E scripts) adds the Swift Package containing the frameworks to the Xcode project. You can also add them manually via Xcode's 'Add Package Dependencies' with a local package path.

Give your agent this brain