Running multiple Expo apps across simulators in parallel
If you work on more than one React Native app at a time, you know the dance. I run several Expo projects side by side every day — client apps at my studio, weshipit, plus Leaf and simgrid on the side — and the hardest part was never the code. It was getting each app onto the right simulator, with its own Metro bundler, without everything stepping on everything else.
That daily friction is exactly why I built simgrid, an open-source CLI that runs multiple Expo apps across multiple iOS simulators and Android emulators in parallel. This post is the story of the pain — and how the tool removes it.
The pain: parallel builds and simulator juggling
Running one Expo app is easy: npx expo run:ios, pick a simulator, done. Running
three or four at once is where it falls apart:
- Simulator conflicts. Each project grabs whichever iOS Simulator it wants — often the wrong one, or one already taken by another app. You end up with two dev clients fighting over the same device.
- Port clashes. Every project wants Metro on
8081. Start a second one and you're manually juggling--portflags and trying to remember which terminal tab serves which bundle. - The alt-tab dance. Four terminals, four Metro instances, four simulators, and no way to tell at a glance which development build is running where. You deep-link the wrong app into the wrong device and lose ten minutes before you notice.
- Boot overhead. Booting iOS Simulators and Android emulators by hand, then starting Metro, then deep-linking the dev client — repeated for every project, every morning.
None of this is hard. It's just death by a thousand papercuts — the kind of repetitive setup that quietly eats an hour out of every day working in a multi-project or monorepo React Native setup.
What I tried first
The usual escalation. First a pile of shell aliases. Then a Procfile and
concurrently to fan out Metro instances. Then a half-broken bash script that
booted simulators by UDID and tried to remember port assignments. Every version
worked until I added one more project — and then the port math and device
routing broke again.
The real problem wasn't the commands. It was that nothing kept track of which project belonged on which device. I needed a small layer that owned that mapping so I didn't have to.
Enter simgrid
simgrid is a Node.js + TypeScript CLI
(MIT-licensed, on npm as simgrid-cli)
that does exactly that one job: route each Expo project to the correct
simulator or emulator, run a dedicated Metro bundler per project, and remember
the mapping — so you can launch your whole grid of apps with a single command.
# install once, globally
npm i -g simgrid-cli
# from any Expo project
simgrid init # wires "start": "simgrid" into package.json
simgrid # interactive device picker, then launch
simgrid --profile ios+android # launch a saved device set in one shot
simgrid status # see which project is mapped to which device, globally
simgrid logs # stream the device's system logs
simgrid doctor # check xcrun / adb / emulator are on your PATH
simgrid stop # stop this project's sessions and deregisterNo config files to write. Pick your devices once with a --profile name and
simgrid saves that set automatically — next time, simgrid --profile ios+android
boots the simulators, starts Metro per project, and deep-links each
Expo dev client
to the device it belongs on.
How it works
Under the hood simgrid keeps a shared device registry across all your projects. When you launch:
- It reads the project's identity (scheme / bundle id) so it knows which app it's about to run.
- It routes that project to a device — interactively the first time, then from the saved profile.
- It boots the simulator or emulator if it isn't already up.
- It starts Metro for that project on its own port.
- It deep-links the dev client so the right app opens on the right device.
Because the registry is global, simgrid status from any project shows the whole
grid — every project-to-device mapping at once. No more guessing which terminal
owns which bundle.
Requirements: Node ≥ 18, macOS + Xcode for iOS simulators, and adb +
emulator on your PATH for Android. It's built for Expo
development builds —
the same workflow you already use with EAS Build.
Try it
If you've ever lost an afternoon to simulator roulette, this one's for you.
simgrid is open source — read the docs,
npm i -g simgrid-cli, and run simgrid from your project. If you build with
Expo or React Native, grab the RSS feed — every post here comes from
real production work.
It scratches my own itch every single day. If it scratches yours too, I'd love to hear what's missing.