Expo Go or a dev build
Which modules run in Expo Go, which need a development build, and how to make one - locally with Xcode or Android Studio, or in the cloud with EAS.
Hey - by the end of this page you'll know whether your stack runs in Expo Go, and if it doesn't,
you'll have a dev build on your simulator or phone that bun run start:dev connects to.
Expo Go is the app from the App Store and Play Store. It carries a fixed set of native modules, so it opens your project in seconds with no build - as long as your stack needs nothing more. A dev build is your own app with Expo's developer tools inside: every native module you picked, your icon and bundle id, and the same fast refresh from your dev server. You build it once and rebuild only when native code changes.
Before you start
- Tier: any. On the Free tier every module runs in Expo Go.
- Time: none if you stay in Expo Go. A local dev build takes 10-20 minutes the first time; an EAS one about 20-40 minutes in the queue.
- Accounts: none locally. For EAS, a free Expo account, plus the paid Apple Developer Program to install an iOS build on a real iPhone.
- Previous tutorial: Quickstart.
1. Check what your stack needs
Six options have native code Expo Go doesn't carry:
| Option | Why it needs a dev build |
|---|---|
storage=mmkv | MMKV is a native key-value store |
ui=unistyles | Unistyles is a C++ style engine on Nitro Modules |
payments=revenuecat | StoreKit and Play Billing |
payments=adapty | StoreKit and Play Billing |
push=expo-notifications | Remote push - Expo Go can't receive it since SDK 53 |
widgets=expo-widgets | The widget is an iOS app extension |
Two more run in Expo Go with less: crash=sentry reports JS errors there but needs a dev build
for native crashes, and analytics=amplitude fills in the full device context only in a dev
build. Local notifications work in Expo Go. Right-to-left layout (Arabic) also needs a dev build:
Expo Go resets the layout direction whenever it opens a project.
setup already made the call - look at the start script in package.json:
expo start --go- every module you picked runs in Expo Go.bun run startopens it there.expo start --dev-client- at least one needs a dev build.bun run starttargets your dev build, and Expo Go won't load the project.
On Starter and Pro, bun run doctor checks the Xcode and Android SDK toolchains only when one of
your modules needs them. The Free tier has no doctor; before a local build, check by hand that
xcode-select -p prints a path inside Xcode.app (iOS) and that ANDROID_HOME points at your
Android SDK (Android).
You should see: --go or --dev-client in the start script. On --go, you're done -
come back when you add a native module.
2. Build it locally
With Xcode (iOS) or Android Studio (Android) installed, one command generates the native project, compiles it and installs it on the simulator or emulator:
bun run iosbun run androidThese are expo run:ios and expo run:android. The first run compiles every native module
from source, so it takes a while; later runs reuse the build cache. For a plugged-in phone, add
--device:
bunx expo run:ios --deviceThe ios/ and android/ folders this creates are generated - never edit them. Native
settings live in app.config.ts, readynative.config.ts and config plugins, and a rebuild
regenerates the folders.
You should see: "YourApp (Dev)" installed next to any other variant, opening the Expo development launcher and then your app.
3. Or build it on EAS
No Mac, or you'd rather not install Xcode? EAS builds it in the cloud with the development
profile from eas.json (developmentClient: true, internal distribution). Link the project
first - Ship to TestFlight has the commands -
then:
bunx eas-cli build --profile development --platform androidThe Android build is an .apk that installs on any phone or emulator from the link EAS prints.
iOS needs one more step. Internal builds install only on registered devices, so register your iPhone first - the command shows a QR code to open on the phone, which installs a profile that tells EAS the device's id:
bunx eas-cli device:create
bunx eas-cli build --profile development --platform iosA device registered after a build needs a new build. To build for the iOS Simulator instead,
add a profile that extends development:
"development-simulator": {
"extends": "development",
"ios": { "simulator": true }
}and build it with --profile development-simulator.
You should see: a QR code and install link when the build finishes. On iOS, enable Developer Mode (Settings → Privacy & Security) the first time you open it.
4. Start the dev server for it
bun run start:devThat's expo start --dev-client: the QR code opens your dev build, not Expo Go. On a
--dev-client stack, bun run start does the same.
You should see: your dev build connect and load the app; saving a file refreshes it as in Expo Go.
When to rebuild
Rebuild the dev build when something native changes: a module or library with native code, a config plugin, the name, bundle id, scheme, icon or splash. JavaScript changes never need a rebuild - they come from the dev server. When the app on the device and your tree disagree, the dev build usually tells you with a "native module not found" error.
If it doesn't work
- "Project is incompatible with this version of Expo Go" or a missing native module - your stack needs a dev build. See A native module is missing in Expo Go.
bun run iosfails before compiling -xcode-select -pmust point at Xcode (Starter and Pro: the "Xcode (dev build)" row ofbun run doctorchecks it), orANDROID_HOMEat your Android SDK for Android.- The iOS EAS build won't install - the device wasn't registered when the build ran.
bunx eas-cli device:create, then build again. - The dev build opens but can't reach the dev server - phone and computer must be on the same
network, or start with
bunx expo start --dev-client --tunnel. - The build fails on credentials - see EAS build or credentials fail.
More in Troubleshooting.
Next
You can run every module you picked. Next, make the app yours: Make it yours.