xbridge
A single Go binary that turns a Mac into a locked-down iOS build API. Drive Xcode builds, simulators, and screenshots from Linux, CI, or plain curl, over HTTP.
A single Go binary that turns your Mac into a locked-down iOS build API. Trigger Xcode builds, drive simulators, grab screenshots, and interact with running apps, from a Linux box, a CI pipeline, or plain curl with nothing more than an HTTP request.
Why
If you’re on Linux most of the time but your app has to build with Xcode, you end up SSH-ing into a Mac, running commands by hand, and rsync-ing artifacts back. That’s fine for one-offs. It’s a bad fit for CI, scripts, auto-generated screenshots, LLM-driven UI testing, and anything that should be reproducible. I wanted an HTTP API that spoke iOS builds, exposed only the verbs I care about, and could be dropped into a pipeline behind a single URL.
How it works
One static Go binary, no runtime dependencies. Run xbridge serve on the Mac and it:
- auto-detects the Xcode workspace and scheme in the current directory,
- boots an HTTP server on
:7900, - exposes a small REST surface:
POST /build,GET /builds/:id/log,GET /simulators,POST /simulators/:udid/tap,POST /simulators/:udid/text,GET /simulators/:udid/screenshot,POST /apps/:bundle/launch, and more.
The same binary is also the client. Pointed at a remote Mac with xbridge remote set mac:7900, every xbridge <verb> translates into one HTTP call. You can skip the client entirely and hit the endpoints with curl from any language or tool.
The server speaks JSON, streams build logs as server-sent events, and holds a small state machine per running build so you can --watch a build-in-progress, cancel it, or fetch just the failure summary.
Notable pieces
Install (Mac, via Homebrew tap):
brew tap xydac/xbridge
brew install xbridge
Serve on the Mac:
cd ~/projects/my-app
xbridge serve
# Server running on :7900
# Detected MyApp.xcworkspace (scheme: MyApp)
Drive from Linux:
xbridge remote set mac:7900
xbridge build --watch # streams build logs as they happen
xbridge sim list # pretty-printed simulator inventory
xbridge sim boot "iPhone 16"
xbridge tap 220 400 # tap coordinates
xbridge text "hello world" # type into the focused field
xbridge screenshot > ui.png
xbridge run # pull, build, install, launch — one command
Or plain curl:
curl http://mac:7900/health
curl -X POST http://mac:7900/build
curl http://mac:7900/simulators/BOOTED/screenshot > screen.png
curl -X POST -d '{"x":220,"y":400}' http://mac:7900/simulators/BOOTED/tap
Why it’s small by design
- Locked-down surface: the server only exposes Xcode and simctl verbs. It does not proxy arbitrary shell commands, so leaving it running on a home LAN is safe.
- Auth-free by default on localhost, opt-in token header for remote access. No TLS in-process; run it behind tailscale or a local nginx if you want transport security.
- Homebrew tap so upgrades are
brew upgrade xbridge, no Gatekeeper warnings because brew builds from source.
What’s next
Simulator video capture, deeper xcodebuild result-bundle integration, a websocket variant for lower-latency tap streams, and a tiny web UI to poke at the surface without shelling in.