Running Your Expo App on a Real Device for Testing
As an Expo developer, you’ve likely spent countless hours running your app on a simulator or emulator. While that’s great for most development, nothing beats the feel of your app on a real device. It’s the only way to truly test performance, native features, and user experience.
There are two primary paths for running your Expo app on a physical device: using the Expo Go app or building a custom development client. The right choice depends on your project’s dependencies.
Method 1: The Fast Path with Expo Go
If your project relies only on the standard APIs that come with the Expo SDK—meaning no custom native modules or libraries outside of what Expo Go supports—this is your go-to method. It’s quick and requires minimal setup.
Prerequisites
- Your Device: An iPhone or Android phone.
- Expo Go: Make sure the free Expo Go app is installed on your device from the App Store or Google Play Store.
- Shared Network: This is the most critical step. Your computer and your mobile device must be connected to the exact same Wi-Fi network. Issues with corporate or university networks that have client isolation are the most common cause of connection failures.
Step-by-Step Guide
- Start Your Development Server: In your project’s root directory, open your terminal and run the command
npx expo start
. - Scan the QR Code: The terminal will display a QR code. Use your device to scan it.
- On iOS: Open the built-in Camera app and point it at the QR code. A notification will pop up. Tap it to open your app in Expo Go.
- On Android: Open the Expo Go app and tap the “Scan QR Code” button to use the in-app scanner.
- Run the App: Expo Go will connect to your computer, download the JavaScript bundle, and run your app. Now, whenever you save changes in your code, they’ll instantly update on your device.
Accessing the Developer Menu
Once the app is running, you can access the developer menu for debugging tools by shaking your device firmly. This menu allows you to open a remote debugger, reload the app, or view a performance monitor.
Method 2: The Professional Path with a Development Build
Once you add custom native modules—such as a specific video player, a payment library, or Firebase—the Expo Go app won’t work anymore. Its core is immutable and doesn’t contain the native code your new library needs. The solution is to create a custom development build, which is a personalized version of Expo Go with your project’s unique native code compiled in.
Prerequisites
- Expo Account: You’ll need a free Expo account.
- EAS CLI: Install the Expo Application Services (EAS) command-line interface by running
npm install -g eas-cli
and then log in witheas login
.
Step-by-Step Guide
- Add the Development Client Library: This library allows your custom-built app to communicate with your development server. Run
npx expo install expo-dev-client
. - Configure the Build Profile: Make sure your
eas.json
file is configured with adevelopment
build profile that has"developmentClient": true
. If you don’t have this file, you can generate it by runningeas build:configure
. - Create the Development Build: This is the process of building the native
.apk
(Android) or.ipa
(iOS) file. It’s done on Expo’s cloud servers and can take 10-20 minutes.- For Android:
eas build --profile development --platform android
- For iOS:
eas build --profile development --platform ios
(Note: This requires a paid Apple Developer account.)
- For Android:
- Install the Build: Once the build is complete, EAS will provide a link and a QR code. Scan the QR code to download and install the app on your device. On iOS, you’ll likely use TestFlight for this.
- Run Your App:
- Start your server with
npx expo start --dev-client
. - Open the new custom app you just installed on your phone. It will automatically connect to your development server.
- Just like with Expo Go, you can shake your device to access the developer menu and debugging tools.
- Start your server with
When to Rebuild Your App
With a development build, you don’t need to rebuild every time you make a change. Your JavaScript code is loaded dynamically from the development server, providing a fast and iterative experience.
You must create a new build only when you change the native code. This includes:
- Adding or removing a native module npm package.
- Upgrading or downgrading an existing native module.
- Changing native configuration files like
app.json
,Info.plist
, orAndroidManifest.xml
(e.g., updating your app icon or package name). - Upgrading your project to a new Expo SDK version.
For everything else—like editing your JavaScript/TypeScript files or changing CSS styles—the Metro server will instantly push the updates to your running app.
This two-path approach makes Expo incredibly flexible, allowing you to choose the right workflow for your project at every stage of development.