Expo Development Client
The `expo-dev-client` package is a fundamental component of the Expo ecosystem, enabling developers to create custom development builds of their React Native applications. Unlike the generic Expo Go app, development builds include your project's specific native code, allowing for the use of custom native modules (third-party native libraries or your own native code) and advanced native configurations without ejecting to a bare React Native workflow. It provides a development environment that closely mirrors production while retaining fast iteration speeds for JavaScript changes. The current stable version is 55.0.28, aligning with Expo SDK 55. Expo SDKs are typically released three times a year, with each release targeting a specific React Native version. Key differentiators include improved debugging tools, a configurable launcher UI for switching between development servers, and seamless integration with EAS Build for cloud-based native builds.
Common errors
-
Failed to load app from http://<IP>:<PORT> with error: The request timed out.
cause The development client installed on your device/simulator cannot connect to the Metro development server, often due to network configuration, firewalls, or an incorrect IP address being advertised by Metro.fixVerify that your device and computer are on the same network. Try running `npx expo start --dev-client --host lan` or `npx expo start --dev-client --host tunnel`. Check firewall settings. Clear the Metro cache with `npx expo start --clear`. -
Module AppRegistry is not a registered callable module (calling runApplication)
cause This error typically indicates an issue preventing the JavaScript bundle from executing on startup, often due to a problem in your application code or Babel configuration, or a React Native version mismatch.fixTry running `npx expo start --no-dev --minify` to simulate a production bundle locally and pinpoint JavaScript errors. Access device logs via Android Studio or Xcode for more detailed stack traces. Ensure `react-native` versions align in `app.json` and `package.json`. -
Could not find the Expo client app
cause While less common with `expo-dev-client` (which creates a custom app), this can sometimes appear if the custom client build itself is outdated relative to your SDK version, or if there was an issue during its installation.fixEnsure your custom development client is up-to-date with your project's SDK. If in doubt, rebuild the native client with `npx expo prebuild` followed by `npx expo run:ios` or `npx expo run:android`. -
XX.X.X is not a valid SDK version.
cause The Expo SDK version used in your project is deprecated or unsupported by the current Expo CLI or tools, or there's a mismatch between your project's SDK and the tools being used.fixUpgrade your project to a supported SDK version using `npx expo upgrade`. If you are using a supported version, ensure your Expo CLI and related tools are also up-to-date.
Warnings
- breaking Major Expo SDK upgrades often introduce breaking changes for `expo-dev-client`. These can include minimum SDK versions, Node.js, Xcode, Android Gradle Plugin, or Java requirements. Always review the changelog for your target SDK.
- gotcha `expo-dev-client` requires a full native rebuild (using `npx expo run:ios` or `npx expo run:android`) whenever native dependencies are added, updated, or native configurations (e.g., in `app.json` config plugins) are changed. JavaScript changes still benefit from Fast Refresh.
- deprecated Starting with SDK 51, Expo Go will support only a single SDK version per release, shifting the primary development workflow towards development builds. Relying solely on Expo Go for development might limit access to newer React Native versions or custom native modules.
- gotcha Connecting an `expo-dev-client` build to the development server can sometimes fail due to network issues, firewalls, or incorrect IP addresses. Unlike Expo Go, it typically connects via LAN or localhost.
Install
-
npm install expo-dev-client -
yarn add expo-dev-client -
pnpm add expo-dev-client
Imports
- isDevelopmentBuild
import DevClient from 'expo-dev-client'; DevClient.isDevelopmentBuild();
import { isDevelopmentBuild } from 'expo-dev-client'; - getUrl
import { url } from 'expo-dev-client';import { getUrl } from 'expo-dev-client'; - DevClientUrl
import { DevClientUrl } from 'expo-dev-client';import { DevClientUrl } from 'expo-dev-client/build/DevClient';
Quickstart
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View } from 'react-native';
import { isDevelopmentBuild, getUrl } from 'expo-dev-client';
export default function App() {
const appUrl = getUrl();
const isDev = isDevelopmentBuild();
return (
<View style={styles.container}>
<Text style={styles.title}>Expo Dev Client Example</Text>
<Text>Is Development Build: {isDev ? 'Yes' : 'No'}</Text>
{isDev && <Text>Development URL: {appUrl || 'N/A'}</Text>}
<Text style={styles.text}>This app is running in a custom Expo Development Client.</Text>
<Text style={styles.text}>It supports native modules and advanced configurations.</Text>
<StatusBar style="auto" />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
padding: 20,
},
title: {
fontSize: 22,
fontWeight: 'bold',
marginBottom: 10,
},
text: {
fontSize: 16,
textAlign: 'center',
marginVertical: 5,
},
});
// To run this:
// 1. npx create-expo-app my-dev-client-app --template bare-minimum
// 2. cd my-dev-client-app
// 3. npx expo install expo-dev-client
// 4. Copy this code into App.tsx
// 5. npx expo prebuild --platform android,ios
// 6. npx expo run:ios (or run:android) to build and launch the custom client
// 7. Then subsequent runs: npx expo start --dev-client