Reference version

Expo Brownfield

Toolkit and APIs for integrating Expo into existing native applications.

Android
iOS
Bundled version:
~55.0.1

expo-brownfield is a toolkit for adding React Native views to existing native Android and iOS applications. It provides:

  • Built-in APIs for bi-directional communication and navigation between native and React Native apps
  • Config plugin for automatic setup of brownfield targets in your Expo project
  • CLI for building and publishing artifacts to Maven repositories (Android) and XCFrameworks (iOS)

Installation

Terminal
- npx expo install expo-brownfield

If you are installing this in an existing React Native app, make sure to install expo in your project.

Usage

Communication API

The Communication API enables bi-directional, message-based communication between the native (host) app and React Native.

Sending messages from React Native to native

import * as Brownfield from 'expo-brownfield'; Brownfield.sendMessage({ type: 'MyMessage', data: { language: 'TypeScript', expo: true, platforms: ['android', 'ios'], }, });

Receiving messages from native in React Native

import * as Brownfield, { type MessageEvent } from 'expo-brownfield'; import { useEffect } from 'react'; function MyComponent() { useEffect(() => { const handleMessage = (event: MessageEvent) => { console.log('Received message:', event); }; Brownfield.addMessageListener(handleMessage); return () => { Brownfield.removeMessageListener(handleMessage); }; }, []); // ... }

Sending messages from native to React Native

import expo.modules.brownfield.BrownfieldMessaging BrownfieldMessaging.sendMessage(mapOf( "type" to "MyAndroidMessage", "timestamp" to System.currentTimeMillis(), "data" to mapOf( "platform" to "android" ) ))
import ExpoBrownfield BrownfieldMessaging.sendMessage([ "type": "MyIOSMessage", "timestamp": Date().timeIntervalSince1970, "data": [ "platform": "ios" ] ])

Receiving messages from React Native in native

import expo.modules.brownfield.BrownfieldMessaging val listenerId = BrownfieldMessaging.addListener { event -> println("Message from React Native: $event") } // Later, to remove the listener: BrownfieldMessaging.removeListener(listenerId)
import ExpoBrownfield let listenerId = BrownfieldMessaging.addListener { message in print("Message from React Native: \(message)") } // Later, to remove the listener: BrownfieldMessaging.removeListener(id: listenerId)

CLI

The expo-brownfield library includes a CLI for building and publishing to Maven repositories (Android) and XCFrameworks (iOS).

Terminal
- npx expo-brownfield [command] [options]

Commands

build:android

Builds and publishes the brownfield library and its dependencies to Maven repositories.

Terminal
- npx expo-brownfield build:android [options]
OptionDescription
-d, --debugBuild in debug mode
-r, --releaseBuild in release mode
-a, --allBuild in both debug and release mode (default)
-l, --librarySpecify brownfield library name
--repo, --repositorySpecify Maven repositories to publish to
-t, --taskSpecify Gradle publish tasks to run
--verboseInclude all logs from subprocesses

build:ios

Builds the brownfield XCFramework and copies the Hermes XCFramework to the artifacts directory.

Terminal
- npx expo-brownfield build:ios [options]
OptionDescription
-d, --debugBuild in debug mode
-r, --releaseBuild in release mode (default)
-a, --artifactsPath to the artifacts directory (default: ./artifacts)
-s, --schemeXcode scheme to build
-x, --xcworkspaceXcode workspace path
--verboseInclude all logs from subprocesses

tasks:android

Lists all available publish tasks and Maven repositories.

Terminal
- npx expo-brownfield tasks:android

API

import * as Brownfield from 'expo-brownfield';

Methods

Brownfield.getMessageListenerCount()

Android
iOS

Gets the number of registered message listeners.

Returns:
number

The number of active message listeners.

Brownfield.popToNative(animated)

Android
iOS
ParameterTypeDescription
animated(optional)boolean

Whether to animate the transition (iOS only). Defaults to false.

Default:false

Navigates back to the native part of the app, dismissing the React Native view.

Returns:
void

Brownfield.sendMessage(message)

Android
iOS
ParameterTypeDescription
messageRecord<string, any>

A dictionary containing the message payload to send to native.


Sends a message to the native side of the app. The message can be received by setting up a listener in the native code.

Returns:
void

Brownfield.setNativeBackEnabled(enabled)

Android
iOS
ParameterTypeDescription
enabledboolean

Whether to enable native back button handling.


Enables or disables the native back button behavior. When enabled, pressing the back button will navigate back to the native part of the app instead of performing the default React Navigation back action.

Returns:
void

Event Subscriptions

Brownfield.addMessageListener(listener)

Android
iOS
ParameterTypeDescription
listenerListener<MessageEvent>

A callback function that receives message events from native.


Adds a listener for messages sent from the native side of the app.

Returns:
EventSubscription

A subscription object that can be used to remove the listener.

Example

const subscription = addMessageListener((event) => { console.log('Received message from native:', event); }); // Later, to remove the listener: subscription.remove();

Brownfield.removeAllMessageListeners()

Android
iOS

Removes all message listeners.

Returns:
void

Brownfield.removeMessageListener(listener)

Android
iOS
ParameterTypeDescription
listenerListener<MessageEvent>

The listener function to remove.


Removes a specific message listener.

Returns:
void

Interfaces

EventSubscription

Android
iOS

A subscription object that allows to conveniently remove an event listener from the emitter.

EventSubscription Methods

remove()

Android
iOS

Removes an event listener for which the subscription has been created. After calling this function, the listener will no longer receive any events from the emitter.

Returns:
void

Types

MessageEvent

Android
iOS

Type: Record<string, any>