Let’s start with answering the question: what is a brownfield application?

The term “brownfield” implies something built with already existing elements. Originally used in urban planning to describe areas that can be repurposed, it was later adopted in mobile app development. A brownfield app is basically an app which is not built from scratch.

What does it mean in practice? It means that we want to run a React Native application as a part of a native app that is already developed with technologies like Java, Kotlin, Objective-C or Swift. In other words, we want to integrate React Native in an existing app.

How does it work?

Let’s assume that we have a native iOS application where we want to create a new screen using react-native app that is already implemented. That screen will navigate to another screen inside the react-native application.

React Native Screen

In order to make it works, we need to do a few things.

Add React Native to the project:

  • First of all, we need to add our React Native app to an existing native project. We will want to decide what parts of the React Native framework you would like to integrate. We will use CocoaPods for it. Let’s edit or create Podfile in the native project and add React and all needed subspecs with path pointed to node_modules and run pod install command

Run a React Native app:

  • When the React Native app is properly linked to the native one, we need to create a class that implements RCTBridgeDelegate – at least thesourceURLForBridge method that is needed to specify which JS bundle will be used.
  • Then create a React Native bridge instance ( RCTBridge ) with the previously implemented class as the delegate and launchingOptions dictionary if needed.
  • Create ViewController where we will set therootView of the react-native app as a view property.
  • Finally, we can push our react-native view controller to the stack

Additional steps:

Note: In debug mode, we need packager to serve JS bundle. However, Apple has blocked implicit cleartext HTTP resource loading. So we need to add the following our project’s Info.plist (or equivalent) file.

In addition, we can add scripts to Build Phases which will build react-native bundle and images for us

export NODE_BINARY=node ../node_modules/react-native/scripts/react-native-xcode.sh

And the script that will run the packager

Navigation issues:

We have all set, however, there is an issue with swipe to back functionality. We are not able to get back to our native screen via a swipe gesture or by means of Go Back button. We need some mechanism that would make possible to say from react-native to the native part that we want back to our native screen or that we want to enable/disable native PopGestureRecognizer . It could be solved by a react-native native module which will send notification by NSNotificationCenter .

BUT wait… Can’t it be done in simpler way? Do we really need to take care of RCTBridgeDelegate, RCTBridge, RCTRootView?

Of course, it might be easier 🙂 We can use react-native-brownfield package which will help us with navigation’s issues and provide a nice API to run a react-native application.

How does it work with React Native brownfield?

We want to achieve exactly the same effect as before but we will use react-native-brownfield library

Add React Native to the project:

The theory is the same as I described in the previous part of this article but with some facilities. In order to run our React Native app in a native one using react-native-brownfield we need to add that package as a dependency to package.json using:


Next, we need to add the React Native app as we did in Add react-native to project point using CocoaPods.

Run a React Native app:

And now the fun begins 🙂 Instead of creating a bridge by ourselves we can simply use ReactNativeBrownfield package.

Import ReactNativeBrownfield package and create the instance of it with the entry file name.

We are ready to run react-native app using startReactNative method of our reactNativeBrownfieldManager

And that’s it. We can push react-native app view controller to the navigation stack with user-friendly API.

Additional steps:

All additional steps are needed to be added here as well

  • Edit Info.plist file to allow connection to the packager
  • Add script to Build Phases to run packager
  • Add script to BuildPhases to bundle JS code and assets

Navigation issues:

react-native-brownfield comes with a solution for the issues mentioned above. It exposes two methods that can be used in JS code to toggle back gesture and pop to a native screen.

  • ReactNativeBrownfield.setNativeBackGestureAndButtonEnabled – to toggle iOS native back gesture
  • ReactNativeBrownfield.popToNative – to pop to the native screen

And voilà! We are ready to go 🙂


It is a popular thing to use React Native within existing native apps especially by larger organizations that have multiple teams working on the same app for multiple platforms. Thanks to React Native brownfield the integration is easier, enjoyable and some issues that exist in every React Native brownfield app are solved 🙂

Working examples of using react-native-brownfield are inside example directory.