Install Expo modules in an existing native project

Edit this page

Learn how to prepare your existing native project to install and use Expo modules and the module API.


If your project is a greenfield React Native app — primarily built with React Native from the start, then see Install Expo modules in an existing React Native project instead of this guide.

This guide provides the steps to prepare your existing native project to install and use Expo modules and the module API.

Prerequisites

The following instructions may not work for all projects. Support for integrating Expo modules into existing projects is still experimental. If you encounter issues, create an issue on GitHub.

You should have a brownfield native project with React Native installed and configured to render a root view. If you don't have this yet, follow the Integration with Existing Apps guide from the React Native documentation and then come back here once you have followed the steps.

Install the expo package

Add the expo package to your project. Ensure you are using a version of the expo package that is compatible with the React Native version in your project.

Terminal
npm install expo

Configuring native apps

Android app

1

Add the following to the gradle.properties file in the android directory:

android/gradle.properties
20newArchEnabled=true
21
22hermesEnabled=true

2

Add the following to the setting.gradle file in the android directory:

android/settings.gradle
1apply from: new File(["node", "--print", "require.resolve('expo/package.json')"].execute(null, rootDir).text.trim(), "../scripts/autolinking.gradle");
2useExpoModules()
3
14include ':app'
25includeBuild("../node_modules/@react-native/gradle-plugin")

3

Inside the android directory, run the following command:

Terminal
./gradlew clean

Once the above command completes, run:

Terminal
./gradlew assembleDebug

4

(Optional) Complete the following steps if you would like to use lifecycle listeners in your app. If you do not set up lifecycle listeners, then additional setup will be required for each module that uses them.

4.1

If you already have a class that extends the Application class you can move to step 3. If you do not have it, we need to create one. Add a file called MainApplication.kt file to your android/app/src/main/java/com/<your-app-package> directory with the following content:

android/app/src/main/java/com/<my-app-package>/MainApplication.kt
1package <my.app.package>
2
3import android.app.Application
4import android.content.res.Configuration
5import com.facebook.soloader.SoLoader
6import expo.modules.ApplicationLifecycleDispatcher
7
8class MainApplication() : Application() {
9 override fun onCreate() {
10 super.onCreate()
11 ApplicationLifecycleDispatcher.onApplicationCreate(this)
12 }
13
14 override fun onConfigurationChanged(newConfig: Configuration) {
15 super.onConfigurationChanged(newConfig)
16 ApplicationLifecycleDispatcher.onConfigurationChanged(this, newConfig)
17 }
18}

4.2

Register the class in the AndroidManifest.xml file.

android/app/src/main/AndroidManifest.xml
77 <application
88 android:allowBackup="true"
9 android:name=".MainApplication"
910 android:fullBackupContent="@xml/backup_rules"

4.3

If you have your own class extending Application, you can add the following. It includes calls to ApplicationLifecycleDispatcher for handling events at the application startup and during device configuration changes.

android/app/src/main/java/com/<my-app-package>/MainApplication.kt
01 override fun onCreate() {
12 super.onCreate()
3 ApplicationLifecycleDispatcher.onApplicationCreate(this)
24 }
5
6 override fun onConfigurationChanged(newConfig: Configuration) {
7 super.onConfigurationChanged(newConfig)
8 ApplicationLifecycleDispatcher.onConfigurationChanged(this, newConfig)
9 }

Override onConfigurationChanged if you have not done so already.

iOS app

1

Add the following to your Podfile in the ios directory:

ios/Podfile
1require File.join(File.dirname(`node --print "require.resolve('expo/package.json')"`), "scripts/autolinking")
12require Pod::Executable.execute_command('node', ['-p',
23 'require.resolve(
34 "react-native/scripts/react_native_pods.rb",
1415end
16use_expo_modules!

2

Open your ios directory in Xcode. From the project navigator, select your project and then select your app target under TARGETS. In Build Settings, using the search bar, search for ENABLE_USER_SCRIPT_SANDBOXING. If it is not already, set its value to No.

3

Run pod install in the ios directory.

Terminal
cd ios && pod install

You will need to do this every time you add a dependency that uses native code.

4

(Optional) Complete the following if you would like to use AppDelegate subscribers. If you do not set up AppDelegate subscribers, then additional setup will be required for each module that uses them.

ios/<MyAppProject>/AppDelegate.swift
11import UIKit
2import ExpoModulesCore
2class AppDelegate: UIResponder, UIApplicationDelegate {
3class AppDelegate: ExpoAppDelegate {
3 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
4override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
4 return true
5super.application(application, didFinishLaunchingWithOptions: launchOptions)