ReadyNative

29 Sep 2026 · 7 min read

Expo Go vs a development build: when to switch

Expo Go runs only the native modules it bundles. When you need a development build, what breaks in Expo Go (push, payments, MMKV) and how to make one.

Expo Go is a prebuilt app from the stores. It ships a fixed set of native modules, and your JavaScript runs inside it. A development build is your own app, compiled with expo-dev-client, so it holds exactly the native code your project needs and still loads JavaScript from the dev server with fast refresh.

The short rule: start in Expo Go, and switch the day you add a library with native code that Expo Go does not bundle, or a feature that needs your own app identity (push tokens, store purchases, widgets, custom URL schemes, entitlements).

The difference in one table

Expo GoDevelopment build
What runs your JSThe Expo Go app from the App Store / Play StoreYour app, built with expo-dev-client
Native modulesOnly the ones Expo Go bundles for its SDKAny library, plus your config plugins
App config (bundle id, icons, permissions, plugins)Ignored - it is Expo Go's appApplied at build time
Remote push notificationsNo (since SDK 53)Yes, on a physical device
In-app purchases (StoreKit, Play Billing)NoYes
Time to first runSeconds: scan a QR codeOne native build, then the same fast loop
When to rebuildNeverAfter adding native code, changing app config or upgrading the SDK

What stops working in Expo Go

Here is what we hit building ReadyNative, where every module records whether it runs in Expo Go. Out of 17 categories, these are the options that need a development build:

Sign-in (Supabase, Clerk, Better Auth), analytics, Sentry, TanStack Query, forms and i18n all run in Expo Go. So a sensible order is: build screens in Expo Go, then make one development build when you reach push or payments.

How to make a development build

Install the dev client once:

npx expo install expo-dev-client

Then pick one way to build it.

On your machine

Needs Xcode for iOS or Android Studio for Android:

npx expo run:ios            # simulator
npx expo run:ios --device   # a plugged-in iPhone
npx expo run:android

In the cloud with EAS

No local toolchain needed; EAS signs the build and gives you a link or QR code to install it:

npx eas-cli@latest build --profile development --platform ios
npx eas-cli@latest build --profile development --platform android

For the iOS Simulator, set ios.simulator to true on the development profile in eas.json. Once the build is installed, start the dev server as usual and open it from the app:

npx expo start --dev-client

When you have to rebuild

JavaScript changes never need a rebuild - fast refresh and EAS Update cover them. Rebuild when you:

If ios/ and android/ are not in your repo (Continuous Native Generation), do not create or edit them by hand: change app.config.ts or a config plugin, then rebuild. To regenerate them locally from scratch, run npx expo prebuild --clean.

Do I lose anything by switching?

Not the dev loop: a development build loads your JavaScript from the dev server with fast refresh, the same as Expo Go. What you add is one native build per change of native code - and in return the app you test is the app you ship, with your bundle id, icons and permissions.

Teammates who only touch JavaScript can keep installing the same development build; share it with an EAS internal distribution link instead of everyone building locally.

Read next: Expo push notifications, set up end to end, the first feature most apps hit that Expo Go cannot run, and Expo's own development builds guide. Building for the stores next? See Ship to TestFlight.

More guides