The short answer is to make development build of your app to use instead of Expo Go. The docs on this topic start here: Introduction - Expo Documentation.
This is a more complete answer below. You might be familiar with some of the concepts already and this is a fuller answer to explain what’s going on:
Modern builds & Classic builds
EAS Build is a cloud service that creates builds like the ones you’d get when running expo run:android
and expo run:ios
(or expo prebuild:{android,ios}
+ running Gradle/Xcode) on your own computer. These builds include only the native code for the modules specified in your package.json’s dependencies. Let’s refer to these builds as modern builds.
Expo Go, on the other hand, includes a preset group of modules. For instance, Expo Go includes the native code for expo-camera
whether or not you use expo-camera
in your project. And due to how we originally designed it, the expo build:{android,ios}
service creates standalone app builds that include the same modules that Expo Go includes, whether or not you use them in your project. Let’s refer to these builds as classic builds.
Different runtimes and runtime versions
Expo Go and all classic builds include the same native modules (technically, it is possible to create slightly customized classic builds but let’s ignore those). In contrast, each modern build may include its own unique set of native modules, and modern builds usually don’t include the exact same set of native modules as Expo Go or classic builds.
This means JavaScript that runs on Expo Go and classic builds isn’t guaranteed to run on a given modern build, and vice versa. If your JavaScript imports expo-camera
and your modern build doesn’t include the native code to access the camera, your JavaScript will fail. And vice versa, if your modern build includes custom native code that’s not inside Expo Go and classic builds, JavaScript that tries to access that custom native code will fail if run on Expo Go.
So, we need a way to say whether a given build is compatible with some given JavaScript code: this is the purpose of runtime versions. A runtime version is a version string that describes the native APIs and other native features of your build. They can be as plain as “1”, “2”, “3”, and so on – you choose how to name and keep track of your versions. What ultimately matters is that the runtime version your JavaScript targets is the same as the runtime version of your build.
Modern builds and Expo Go
Since modern builds and Expo Go include different native modules, they are different runtimes. JavaScript written for one is not guaranteed to run in the other.
When we make modern builds (e.g. with EAS Build, like in this case) and have custom runtimes with custom runtime versions, we need a replacement for Expo Go, which is no longer guaranteed to be compatible with our JavaScript. This replacement is a development build of your app that you create by adding the expo-dev-client
module. This is our Getting Started guide: Getting Started - Expo Documentation.
You can share your development builds with teammates using Android’s side-loading and iOS’s ad-hoc provisioning profiles (Apple’s default recommended way for sharing development builds amongst a team) or an enterprise provisioning profile if you have that type of account.