In an Expo project, what does expo-dev-client add to a debug build, and how does that development build find the Metro dev server?
answer
- launcher screen and dev menu
- servers on the local network
- exp+ plus the slug as scheme
- expo-development-client/?url= deep link
- --dev-client, --go, press s
basics
~20 sexpo-dev-client adds a launcher screen, an extended dev menu and the ability to load published updates. The build finds Metro through the launcher's list of dev servers on the network, or through a QR code deep link carrying the server URL.
solid answer
~40 s`expo-dev-client` turns a Debug build into a development build: it adds a **launcher** screen that lists development servers and lets you enter a URL, an extended **dev menu**, and support for opening published updates. Its config plugin also registers a custom URL scheme, by default `exp+` followed by the app's slug (`addGeneratedScheme` defaults to `true`). When `package.json` depends on `expo-dev-client`, `npx expo start` switches to development-build mode, prints *Using development build*, and its QR code encodes `exp+<slug>://expo-development-client/?url=<manifest URL>`, which opens your build and points it at Metro. The launcher also finds a bundler on the local network, or through the same Expo account signed in on both sides. `--dev-client` and `--go` force a target, and pressing `s` switches between them.
code
bash · 4 linesnpx expo install expo-dev-client
npx expo run:android # native rebuild: the launcher is native code
npx expo start # prints "Using development build"
npx expo start --go # force Expo Go insteadgo deeper
Recall that expo-dev-client adds a launcher and dev menu, and that scanning the QR code from npx expo start opens your build.
Explain the connection paths: network discovery, account sign-in, and the exp+slug deep link carrying the manifest URL, plus how the CLI picks its target.
Show how you debug a build that cannot find Metro, and how one shared development build serves many developers and branch previews.
Decide how development builds and their servers are shared across a team so that switching context never costs a native rebuild.
## What a plain Debug build knows about Metro A React Native Debug build loads its JavaScript from a development server instead of an embedded bundle. By itself it looks for the server at a host and port it was configured with, which works on a simulator but gets awkward across devices, networks and teammates. `expo-dev-client` adds a proper front door. ## What expo-dev-client adds - **The launcher**: the first screen when you open the app from the home screen. It lists development servers it can find, accepts a URL, and can open published updates of the app. - **An extended dev menu**, opened by shaking the device or with a keyboard shortcut, for reloading, debugging and switching what the build is running. - **A generated URL scheme**: the config plugin registers `exp+<slug>` on iOS and Android, derived from the app config's `slug`, lowercased, with characters that are not allowed in a scheme removed. Set `addGeneratedScheme: false` in the plugin options to skip it. - **Integration with `npx expo start`**, so the CLI produces links that open the development build rather than Expo Go. Because the launcher and scheme are native, adding `expo-dev-client` itself requires a native build. ## How the build finds Metro 1. **Local network discovery**: if a bundler is detected on the same network, the launcher shows it and you tap to connect. 2. **Account sign-in**: signed in to the same Expo account in the CLI and the development build, the launcher can list your running servers. 3. **QR code or deep link**: `npx expo start` prints a QR code encoding a URL of the form `exp+<slug>://expo-development-client/?url=<encoded manifest URL>`. Scanning it opens your app through its scheme and hands it the server address. 4. **Keyboard shortcuts**: pressing `a` or `i` in the CLI opens the project on an Android emulator or iOS Simulator. ## How npx expo start picks the target | Situation | What the CLI targets | |---|---| | `expo-dev-client` is a direct dependency, no flags | the development build (*Using development build*) | | no `expo-dev-client`, no flags | Expo Go | | `--dev-client` | the development build, even without the library | | `--go` | Expo Go | | pressing `s` while running | switch between the two | Passing both `--dev-client` and `--go` is an error. The docs note that a development build without `expo-dev-client` is possible: start the server with `--dev-client`, or the QR code opens Expo Go. ## Troubleshooting the connection - **The launcher shows no servers**: device and computer are on different networks, or the network blocks discovery. Scan the QR code, or use a tunnel host for the dev server. - **The QR code opens Expo Go**: the project has no direct `expo-dev-client` dependency and the server was started without `--dev-client`. - **The QR code does nothing**: the installed build predates `expo-dev-client` or the scheme; rebuild it. - **A teammate's server appears**: the launcher lists what it can find; confirm the host before debugging someone else's bundle. ## Why teams want the launcher One shared development build can serve many people: each developer points it at their own Metro, reviewers open a published update from a branch, and nobody reinstalls the app for a JavaScript-only change. The launcher is what makes that switching cheap. ## Sharing one build across a team The launcher changes how a team works with builds: - **One build, many servers**: each developer runs `npx expo start` on their own machine and opens the same installed development build against it. - **Branch previews**: reviewers open a published update of a branch from the launcher instead of installing a new app, as long as the branch has no native changes. - **Fewer reinstalls**: the build is replaced only when native code changes, which is exactly when the launcher cannot help. The rule of thumb that follows: JavaScript moves through Metro or updates, native code moves through a new build, and the launcher is the switch between JavaScript sources.
- What URL scheme does expo-dev-client register for an app whose slug is habit-loop?`exp+habit-loop`. The plugin lowercases the slug, removes characters not allowed in a URI scheme, and adds the `exp+` prefix to avoid leading digits and to distinguish it from user-defined schemes. `addGeneratedScheme: false` turns it off.
- The QR code from npx expo start keeps opening Expo Go instead of the team's development build; why?The CLI targets the development build automatically only when `expo-dev-client` is a direct dependency. Without it, the default is Expo Go. Install `expo-dev-client` and rebuild, or start the server with `--dev-client`.
saying these in an interview costs you the question
- expo-dev-client can be added with only a Metro reload
- npx expo start always targets Expo Go unless told otherwise
- The development build must be rebuilt to switch Metro servers
- The dev client scheme is the same for every Expo app
- Development builds cannot exist without expo-dev-client