mobster expo puts your Expo or React Native app on a simulator or your iPhone and checks it. One command opens the JavaScript you’re editing on the phone and says whether a screen shows what it should. The same app builds for mobster test and CI, with the JavaScript inside, so a check needs no Metro.
Everything runs on your Mac: Metro, npx expo prebuild, xcodebuild, npx expo run:ios and eas build --local. Mobster never builds on Expo’s servers.
Check it on your iPhone
From your app’s folder:- Mobster reads
package.jsonand the Expo config (app.json, orapp.config.jsthroughnpx expo config). - When nothing answers on port 8081, it starts
npx expo start --lanin the background. - It opens the app on the device: your dev client when the app has
expo-dev-client(exp+<slug>://expo-development-client/?url=…), else Expo Go (exp://…). A phone reaches Metro at this Mac’s address on your Wi-Fi, so both need the same network. A simulator uses127.0.0.1. - With
--expect, it reads the screen’s accessibility tree until every text is there, up to--waitseconds (45 by default, for the first bundle), and saves a screenshot. It exits 1 when one isn’t there.
--path settings/profile opens a screen by the app’s own deep link (its scheme) once the app is up. Without --device, Mobster uses your iPhone, else the only device it sees.
The dev client has to be on the device first. Build and install it once:
npx expo run:ios --device <UDID> --configuration Debug --no-bundler, which signs it with the team in your Xcode project and installs it. Expo Go comes from the App Store.
After a change
r in npx expo start does. Then check again with mobster expo preview --expect …, or let your coding agent do the loop through mobster mcp: expo_preview opens the app on a device and expo_reload reloads it, and each returns the screen. A simulator needs no plan; a real iPhone uses the same plan check as the other phone tools. See the MCP server.
mobster expo stop stops the Metro that preview or dev started.
The dev loop
- It starts this project’s Metro, or reuses the one it started before. A Metro on port 8081 that serves another project is left alone and the next free port is used.
- When the device has no dev client, it builds one (
npx expo run:iosfor an iPhone, a Debug build for a simulator) and installs it.--no-installstops there with the command to run instead. - It opens the app, then polls your source files (
.js,.jsx,.ts,.tsx,.json, outsidenode_modules,iosandandroid) and reloads the app on each save. --check .mobster/checksrunsmobster test --device NAMEon those checks once the app is up.--oncestops after that.- ctrl+c stops the Metro this command started. A Metro that was already running stays running.
mobster expo dev exits 1 with Metro’s own text, the file and the line (cut to 600 characters). After a save, it prints the same text and keeps watching, so the next save tries again. mobster expo preview --expect ends its wait the same way, and also when the dev client shows its red error screen. --json prints one JSON line per event (metro, opened, reloaded, failed, checks).
Mobster doesn’t replace Metro’s fast refresh: it reloads the whole app on a save, which also picks up changes fast refresh skips.
Over the API
The Mac app starts and watches the dev server through the local API:
A Metro that a route started is stopped when Mobster quits.
Builds for checks and CI
A Debug React Native build loads its JavaScript from Metro, and a check doesn’t start Metro. So Mobster builds Release for the simulator, with the bundle inside the app:- When the app has no
iosfolder,npx expo prebuild --platform iosmakes it first. CocoaPods has to be installed. --install --device "iPhone 17 Pro"installs it on a Mobster simulator.--debugbuilds Debug instead, for a simulator dev client that loads from Metro.--eas developmentbuilds that EAS profile on this Mac witheas build --local. A simulator profile’s.appis unpacked into.mobster/expo/eas/, and--installinstalls it.
mobster test pr and mobster ci do the same on their own: in an Expo or React Native project they build Release, after npx expo prebuild when there’s no ios folder. A check names the build the usual way:
.mobster/checks/home.yaml
What Mobster found
ios folder. preview is for Expo apps.
Mobster reuses Metro only when its status names this project. Before stopping it, Mobster checks the process group, command and project folder; it leaves an unverified or replaced process alone. --check runs after the first open and after every successful reload.