This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.
Use Fast Refresh with Metro on a remote simulator
Edit page
Connect a development build on Expo Simulators to Metro through a tunnel so that source changes reach the remote device with Fast Refresh.
Expo Simulators is a limited-access preview. It is not included with paid or free plans and is currently available only to select partners. Join the waitlist if you are interested in trying it.
To see source changes on a remote device without a new build, connect a development build to Metro on your computer. Metro runs locally, a tunnel makes it public, and the development build on Expo Simulators loads JavaScript from that tunnel. After the first bundle loads, Fast Refresh sends each edit to the remote app.
A release build contains the JavaScript from build time. If you connect a release build to Metro, Fast Refresh does not work. Use a development build that includes
expo-dev-client.
Choose the build for the goal
Connect a development build to Metro
1
Create a development build for the simulator
If you cannot create the native build on your computer, add an EAS Build profile with both developmentClient: true and ios.simulator: true:
Create the build before you start the session:
For Android, run the same command with --platform android. The profile produces an APK.
2
Start Metro with a tunnel
The remote device must reach Metro over the internet. Start Metro with the Expo tunnel before you start the session, because EAS opens the Metro URL while the session starts:
EXPO_UNSTABLE_TUNNEL_V2=1 selects a tunnel that is signed for your Expo account. It works with an EXPO_TOKEN or a robot user, and it accepts any --port. Use your own free port if another Metro process uses port 8081.
From SDK 58, npx expo start --tunnel uses this tunnel by default and ignores EXPO_UNSTABLE_TUNNEL_V2. You can leave the variable out in an SDK 58 project.
3
Start the session with the build and the Metro URL
Pass the build ID and the development client URL:
Replace <scheme> with the scheme value from your app config, or with exp+<slug>. expo-dev-client adds the exp+<slug> scheme to a development build. Here, <slug> is the slug from your app config in lowercase, without characters that are not valid in a URL scheme. Do not use the slug without the exp+ prefix. URL-encode the Metro URL when it contains a path or a query.
The launch arguments hide the developer menu onboarding screen and stop the developer menu from opening at launch. Add --launch-arg "-EXDevMenuShowFloatingActionButton" --launch-arg "0" to hide the floating button. These -EXDevMenu* launch arguments work only on iOS. For an Android session, do not pass them.
On SDK 58 and later, you can control the same behavior on both platforms from the URL instead. Add __expo_disable_onboarding=1, __expo_disable_fab=1, and __expo_disable_auto_launch=1 as query parameters of the development client URL. SDK 58 also accepts the <scheme>://?__expo_url=<encoded-public-metro-url> form that npx expo start prints. The expo-development-client/?url= form in the example keeps working, with the legacy disableOnboarding=1, disableFab=1, and disableAutoLaunch=1 parameters placed next to url. See Using launch URLs in automation scenarios.
4
Connect a local development build
The start command installs a development build only from EAS Build, a fingerprint, or an archive URL. For a local development .app, start a blank session and connect through agent-device:
alert accept accepts the Open in dialog if it appears. If the app shows the development client launcher instead of your project, press Enter URL manually, enter the Metro manifest URL, and press Connect.
Keep the loop reliable
- Run exactly one Metro process for the session.
- Start Metro before the session when you pass
--open-url. - Take screenshots only after the development build connects to Metro.
- The first bundle over the tunnel is slow. Later Fast Refresh updates are fast.
- If the first connection fails, stop the session and Metro, then repeat the steps one time. Do not reconnect a release build.
Common questions
Who can reach my Metro server through the tunnel?
Anyone who has the URL. The tunnel URL is public while the tunnel runs. A random URL is hard to guess, but the URL does not require authentication. Share the URL only with the session, and stop Metro when you finish. See Expo Simulators security model.