Capacitor iOS apps: build once on a Mac, update over the air
Most Capacitor changes are web code. Build the iOS shell once on a cloud Mac, then ship HTML, CSS and JavaScript fixes over the air with OtaKit, without Xcode or App Review waits.
· 6 min read
Need a Mac for this? NoMac gives your agent full macOS with Xcode, from $9.99 a month, billed by the second. Start now →
If your iOS app is built with Capacitor, you need a Mac far less often than you think. A Capacitor app is a native shell around a web app. The shell needs Xcode. The web app, which is where most of your changes happen, does not.
So the efficient setup is: build the native shell on a Mac when something native changes, and ship everything else over the air. This guide pairs a NoMac session for the first part with OtaKit, our friends' open-source live update service for Capacitor, for the second.
Needs a Mac: adding or upgrading a plugin, changing permissions or Info.plist, upgrading Capacitor, app icons and the first store build. Does not: HTML, CSS, JavaScript, copy, layout and most bug fixes.
1. Add live updates before the native build
The OtaKit plugin is native code, so it must be inside the binary you ship. Add it locally on Windows, Linux or anywhere:
npm install @otakit/capacitor-updater
2. Build the iOS shell on a cloud Mac
nomac start --json nomac sync . nomac ssh -- 'npm ci && npm run build && npx cap sync ios' nomac ssh -- xcodebuild -project ios/App/App.xcodeproj -scheme App \ -destination 'platform=iOS Simulator,name=iPhone 17 Pro' build
nomac sync skips node_modules, dist and Pods, so the Mac installs dependencies itself. Check the result in the simulator (see the simulator guide), then archive and upload to TestFlight with your own signing, or hand signed releases to CI. Stop the Mac when you are done:
nomac stop --json
3. Ship web changes without a Mac
Once that build is installed on users' phones, web-only changes go out from your own machine:
npm run build npx -y @otakit/cli@latest upload --release
OtaKit handles channels, staged rollouts, automatic rollbacks and delta updates, and it is free for 5,000 updates a month. Apple permits interpreted code updates that do not change an app's primary purpose; OtaKit's guide to Apple's rules on live updates covers where that line is.
What this does to your Mac hours
- ·A native build and simulator check: typically well under an hour on a session.
- ·A week of web fixes: zero Mac time.
- ·A Capacitor or plugin upgrade: one more session. For many apps that is a few times a year, which fits comfortably in NoMac's smallest plan.
Let one agent do both
Connect both MCP servers and your agent can pick the right path for each change:
claude mcp add nomac -- npx @nomac/cli mcp claude mcp add otakit -- npx -y @otakit/cli@latest mcp
If a change touches native code, plugins, permissions or Capacitor itself, build and test it on a NoMac session. Otherwise ship it with OtaKit to the staging channel first. Never promote to production without asking me.
Capacitor-specific guides live on the OtaKit blog. For everything that needs a Mac, start with giving Claude Code a Mac.