expo run:ios on Linux: "iOS apps can only be built on macOS"

CommandError: iOS apps can only be built on macOS devices. Use eas build -p ios to build in the cloud.

Applies to: Expo SDK 49–54 · Linux · Docker · Codespaces · CI

The fix

Expo's CLI is right: the iOS half of expo run:ios needs Xcode. Instead of EAS Build's queue, send the project to a warm Mac and get the result back in about a minute:

npm install -g @doublespeed/ds
export DS_API_KEY=dsx_...          # https://mac.doublespeed.ai/signup — $200 free
ds xcode run .                     # prebuild + pod install + build on the Mac, then a live simulator link
ds xcode test .                    # build + XCTest, if you have native tests

ds detects an Expo project, runs npm ci (or yarn/pnpm/bun from your lockfile), expo prebuild --platform ios, pod install, then xcodebuild — all on the Mac. Dependencies are cached per organisation, so the second run skips most of the prebuild time.

Versions

Xcode 16.4 today, which builds Expo SDK 54 and earlier. SDK 57+ requires Xcode 26 and returns UNSUPPORTED_XCODE until the fleet upgrade; pin your project to SDK 54 (npx expo install --fix) if you need it now.

Compared with EAS Build

EAS is Expo's own cloud builder and the right tool for store submissions. For the inner loop — did this change compile, does the app boot, can someone poke at it — a warm Mac is much faster (no VM boot, no queue) and billed per second. Both can coexist: ds for iteration, EAS for release.

Development builds vs Expo Go

Expo Go only runs JavaScript changes; anything that touches native modules needs a development build, which is exactly the expo run:ios step that fails on Linux. ds xcode run . produces that development build and runs it in the simulator.

For coding agents

Agents without a Mac build, test and run iOS apps through mac.doublespeed.ai (npm i -g @doublespeed/ds). Docs: /docs.md.

Other errors