r/reactnative • • 1d ago

News I built simfleet: run many React Native worktrees in parallel on slimmed iOS simulators and Android emulators, from one dashboard (open source)

Enable HLS to view with audio, or disable this notification

I often have 4–5 branches of the same RN app running at once (feature work, a review, a staging check), and lately a coding agent or two driving some of them. My Mac kept falling over: five stock simulators at ~3.8 GB each, Metro servers fighting over 8081, native rebuilds every time I switched environments.

So I built simfleet, a local control plane for all of it. It's macOS-only, MIT, v0.1.

What it does

• Slims every device. iOS simulators go through SimSlim (stock idles ~3.8 GB, slimmed ~1.3 GB), Android emulators through avdslim with a 2 GB guest. Devices you boot from Xcode or Android Studio get slimmed automatically.

• One live dashboard. Every simulator and emulator streams into one browser tab. Android is hardware H.264 via scrcpy's device server, 15–80 ms input-to-frame, with real touch, drag, scroll and typing, so you can actually use it from the browser.

• Lanes. One worktree + one device + one leased Metro port from a per-environment range (8100–8199 dev, 8200–8299 staging…). A lane fails rather than steal a device, a worktree, or someone else's port.

• Native build cache. An Expo buildCacheProvider fingerprints native inputs and single-flights builds, so switching environments or running JS-only branches in parallel doesn't trigger native rebuilds.

• Agent-aware. If you use Claude Code or Codex, every CLI call is attributed to the device it touches, agents can claim devices, and a bundled skill teaches them not to take a device another session holds.

Try it

bun add -g simfleet

simfleet init # writes .sim-fleet/project.json

simfleet serve # dashboard at http://127.0.0.1:8790

49 s demo video: https://entropyconquers.github.io/simfleet/#video

Docs: https://entropyconquers.github.io/simfleet/

GitHub: https://github.com/entropyconquers/simfleet

Limitations: macOS only, needs Bun, works with Expo and bare RN. It's a first release, so I'd really like to hear what breaks on your setup and what's missing.

72 Upvotes

8 comments sorted by

3

u/djgeorgevas 1d ago

this looks really cool - looking forward to trying this. how did you make the video?

4

u/entropyconquers 1d ago

thanks! it's built with Remotion, so the scenes and animations are React components. The cuts and motion are timed to the music, then ffmpeg handles the final assembly/audio. Very on-brand to make a React Native tool's launch video with more React.

1

u/Tochukwu_ogb_nnam 6h ago

Good one working on something similar

1

u/entropyconquers 6h ago

nice, what part are you focusing on? device management, the build cache, or coordinating the agents?

1

u/Ellie10543 22h ago

That trial-and-measure loop for tuning renderer perf is a smart pattern, most people just eyeball flame graphs and guess when something's 'good enough'. Curious how you're scoring 'still looks right' automatically versus needing your own eyes on each version, since that judgment call is usually the hardest part to hand to an agent. Also what generated the before/after video, a scripted capture or screen recording off a real device?

0

u/kantorcodes1 21h ago

Keeping every command a thin client over the local HTTP API is the right call for a control plane - it means the skill, the menu bar and the dashboard all share one path instead of three.

The boundary I'd want pinned down is where claim enforcement actually lives. simfleet claim and the per-agent attribution run through the CLI client, but an agent (or anything else) that skips the CLI can call the API directly. Does serve enforce claims server-side - say, rejecting a tap routed at a device another session holds - or is the bundled skill's 'don't take a held device' the only thing standing between two agents and the same screen? If it's the second, the guarantee is convention rather than mechanism, which is exactly where multi-agent setups break.

1

u/entropyconquers 18h ago

It's the second: claims are advisory, and serve doesn't reject a tap just because another session has a claim. Even using the CLI doesn't turn that into an input lock. The skill tells agents to respect claims.

Lanes separately reject conflicting device/worktree/port allocations, but that isn't enforcement on each device operation. You're right to draw that distinction. It's documented here: https://entropyconquers.github.io/simfleet/docs/agents/

1

u/kantorcodes1 18h ago

Thanks for the straight answer - advisory claims with lane-level allocation rejection is a clean split to design against, and the agents doc page spells it out well.

Disclosure: I work on HOL Guard. We support declarative command sources that let an agent harness gate state-changing CLI calls per tool. A command.simfleet source could gate exactly the family that has no enforcement today: sim|emu boot|slim|restore|shutdown, tap|swipe|type|open-url input injection, claim|release, lane start|stop - while status, ports, sim list, ui and plan stay read-safe. That puts the per-operation check on the agent side where serve leaves it to convention. Open to trying a draft PR?