Introduction to development builds
Edit this page
Why use development builds and how to get started.
When you created your first React Native project with npx create-expo-app
and ran it with npx expo start
, you most likely started off using the Expo Go app for development. Expo Go is a native app that we (as in Expo) built and submitted to the Google Play Store and Apple App Store so you could get coding quickly. It is a sandbox app with a number of native libraries included within (see the dependencies list). This means that developers may update their app's JavaScript code on their local machine and see the changes on Expo Go.
A React Native app consists of two parts: the native app (Expo Go) and the JavaScript bundle (npx expo start
).
The native app (Expo Go) is immutable once installed. Native build tools are required to create this bundle, and it needs to be signed to be installable on real devices. To add a new library with native code or change metadata that is shipped with the app (for example app name, icon, splash screen) the app needs to be rebuilt and re-installed on the device.
The JavaScript bundle (npx expo start
) is where your app's UI code and business logic are. In production apps, there is one main.js bundle that is shipped with the app itself. In development, this JS bundle is live reloaded from your local machine. The main role of React Native is to provide a way for the JavaScript code to access the native APIs (Image, Camera, Notifications, and more). However, only APIs and libraries that were bundled in the native app can be used.
Since the native app bundle is immutable, this means that when you're using the Expo Go app for development, you can only rely on the native code and tools that exist in Expo Go. The only way to get around it is to build your native app yourself instead of using Expo's pre-packaged sandbox. This is exactly what a Development Build is, your own version of Expo Go, where you are free to use any native libraries and change any native config.

In this tutorial video Beto explains what each of them is, and when to choose a development build.
Why use a development build (a.k.a what can't you do in Expo Go and why)
Expo Go is the perfect tool for learning, prototyping, and experimenting, but most production apps will convert to using development builds sooner rather than later. It helps to know exactly what is impossible in Expo Go and why, so you can make an informed decision on when and why to make this move.
Use libraries with native code that aren't in Expo Go
Consider react-native-webview
as an example, a library that contains native code, but is included in Expo Go. When you run npx expo install react-native-webview
command in your project, it will install the library in your node_modules directory, which includes both the JS code and the native code. But the JS bundle you are building only uses the JS code. Then, your JS bundle gets uploaded to Expo Go, and it interacts with the native code that was already bundled with the app.
Instead, when you try to use a library that is not included, for example, react-native-firebase
, then you can use the JS code and hot reload the new bundle into Expo Go but it will immediately error because the JS code tries to call the native code from the React Native Firebase package that does not exist in Expo Go. There is no way to get the native code into the Expo Go app unless it was already included in the bundle that was uploaded to the app stores.
Test changes in app icon, name, splash screen
If you're developing your app in Expo Go only, you can build a store version that will use your provided values and images; it just won't be possible to test it in Expo Go.
These native assets are shipped with the native bundle and are immutable once the app is installed. The Expo Go app does show a splash screen, which is your app icon on a solid color background. This is a dev-only emulation to view how the splash screen will probably look. However, it is limited, for example, you cannot test SplashScreen.setOptions
to animate the splash screen.
Remote push notifications
While in-app notifications are available in Expo Go, remote push notifications (that is, sending a push notification from a server to the app) are not. This is because a push notification service should be tied to your own push notification certificates, and while it is possible to make it work in Expo Go, it often causes confusion for production builds. It is recommended to test remote push notifications in development builds so you can ensure parity in behavior between development and production.
Universal Links / App Links
Both Android App Links and iOS Universal Links require a two-way association between the native app and the website. In particular, it requires the native app to include the linked website's URL. This is impossible with Expo Go due to the aforementioned native code immutability.
(iOS device only) open projects using older SDKs
Expo Go can only support one SDK version at a time. When a new SDK version is released, Expo Go is updated to support the newer version, and this will be the only version of Expo Go available to install from the stores.
If you're developing on an Android Device, Android Emulator, or iOS Simulator, a compatible version of Expo Go can be downloaded and installed. The only platform where this is impossible is iPhone devices because Apple does not support side-loading older versions of apps.
How to convert from Expo Go to a development build
To migrate from Expo Go to a development build, you'll need to:
1
Install the expo-dev-client
The Expo Dev Client library includes the launcher UI (shown in the screenshots below), dev menu, extensions to test updates, and more. The Expo Go app has the dev menu built in, and that's why you need to install it separately for a development build.
2
Build your native app using native build tools
The details on how to build the native app are platform-dependent and are covered in the next guide.