Learn how to add custom native code to your Expo project.
Expo projects can use both third-party React Native libraries with native code and your own custom native code. Creating a development build allows you to include your specific native dependencies and customizations and not what's in the latest Expo SDK. These native customizations can be any React Native library or your own custom native code.
For most third-party native libraries, autolinking makes it easy. All you have to do is install the package and create a new development build to use the module. Some modules might also need a config-plugin for additional native customizations. When adding your own custom native code, the approach varies based on how you want to work with native code.
By default, Expo projects use Continuous Native Generation (CNG). This means that projects do not have android and ios directories containing the native code and configuration. Instead, the native directories are generated right before building the app and is based on your app config and native modules in package.json. This simplifies the management and upgrading of native code.
It might seem you cannot add custom native code to a project using CNG. However, you can still add that by creating a local Expo module.
Local Expo Modules function similarly to Expo Modules used by library developers and within the Expo SDK. They are not published to npm. Instead, you create them directly inside your project.
You can opt out of CNG and directly manage the code and configuration inside your android and ios directories. To generate these directories, run
npx expo prebuild or compile your app locally (
npx expo run android or
npx expo run ios). You can also create a development build before compiling your app locally. To do so, run
npx expo install expo-dev-client before
# Build your native Android project
npx expo run:android
# Build your native iOS project
npx expo run:ios
npx expo run:android requires Android Studio and the Android SDK to be installed. See how to setup environment.
npx expo run:ios requires Xcode (macOS only) installed on your computer. See how to setup environment.
run commands will prebuild your project to generate all the native code within your project directory. If you manually modify the android or ios directory, you cannot re-run
npx expo prebuild safely, as this may overwrite your changes.
If you install a library with Expo config plugin, you'll need to follow a few steps:
plugins array in the project's app config.
npx expo prebuild to sync the changes before rebuilding the native app. This process often involves tasks like adding required permissions to the AndroidManifest.xml or Info.plist.
npx expo prebuild --clean. This command will delete and re-generate the native directories from scratch.
If you manually modify the android and ios directories, you must set up new libraries manually. Running
npx expo prebuild may not work as expected because the project is now in an unpredictable state (think of this like running
yarn after manually modifying your node_modules directory).
If you want to make static changes to your native project files, such as AndroidManifest.xml or Info.plist, and still have access to prebuilding, then create a config plugin to see how you can hook into the prebuild process to make those changes.
Suppose you have decided to roll your app back to being fully managed (no android or ios directories in your project directory). In that case, you can check out your most recent commit before executing
npx expo run:[android|ios], then run
npm install again to restore the state of your node_modules directory.
Once you have customized the native code in your project, you can use the
When you're ready to ship your app, you can build it with EAS Build the same as you were building it before adding custom native code. Alternatively, you can archive and sign it locally. Unsurprisingly, we recommend EAS Build!
# Install the CLI
npm i -g eas-cli
# Build your app!
eas build -p all
Apart from adding custom native code to a project, the Expo Modules API enables developers to build reusable modules for Expo and React Native projects using Swift, Kotlin, and TypeScript. These modules are often published to npm. They can also be included as separate packages within a monorepo. We use the Expo Modules API for most modules in the Expo SDK.
Another option is to use React Native's Core Native Modules API, which may require some C++ knowledge in addition to Objective-C and Java. Most React Native modules in the ecosystem are built using this API because it is and always has been part of React Native. The Expo Module API is new and intends to solve many of the pain points of using the core API.