An iOS build machine on a Mac Mini M4: Xcode's AI agents, xcodebuild and self-hosted CI

Building an iOS app has one hard requirement no cross-platform trick removes: Xcode, and Xcode only runs on macOS. That does not change when a coding agent, not a person, is doing the building; it still needs the same Mac, the same simulators and the same signing tools a human developer would reach for. A laptop can be that Mac for as long as it stays open, but an agent mid-way through a long test run or an overnight build queue does not benefit from a lid closing. An always-on Mac Mini M4, reachable the same way as any other remote AI coding setup, keeps Xcode and its agents running regardless of what the laptop that started the session is doing.

Why iOS work needs a Mac, and so an iOS-building agent needs one too

Xcode is Apple's own IDE and the only supported way to build, sign and submit an iOS app, and the current release, Xcode 27, only installs on a Mac running "macOS Tahoe 26.6 or later" on Apple silicon (developer.apple.com, xcode-release-notes/xcode-27-release-notes, checked September 2026). Apple enforces this at the point of submission too, not just at build time: since 28 April 2026, apps uploaded to App Store Connect must be built with the iOS 26 SDK or later, alongside matching minimums for iPadOS, tvOS, visionOS and watchOS (developer.apple.com/news/upcoming-requirements, checked September 2026), which in practice means a current Xcode install.

An agent asked to open a project, run its test suite, or produce an archive for TestFlight calls the same Xcode toolchain a human developer would, on the same operating system, with the same simulators installed. There is no separate, lighter iOS build path for automation to take instead.

Why an always-on Mac Mini, not the laptop Xcode is already running on

A laptop with Xcode installed already satisfies the hard requirement above, but it also has to stay open, awake and connected for as long as an agent is mid-build, mid-test-run, or waiting on a slow simulator boot; closing the lid to catch a train ends the session along with it. An always-on Mac Mini M4 removes that constraint the same way it does for any other kind of unattended coding agent: plugged in at a desk, it keeps Xcode, the simulators and whatever agent is driving them running long after the laptop that started the session has gone to sleep.

Reaching that agent works exactly like the setup in the remote AI coding guide: Tailscale puts both machines on the same private network, mosh keeps a session alive across sleep and roaming Wi-Fi, and herdr keeps the agent process running between attaches. An iOS build machine is a remote coding machine that happens to run Xcode.

Xcode's own agents come first: Claude Agent and Codex through the Model Context Protocol

The most direct way to point an AI agent at an iOS project is the one Apple shipped into Xcode itself: Xcode 26.3 "makes its capabilities available through the Model Context Protocol, an open standard that gives developers the flexibility to use any compatible agent or tool with Xcode" (apple.com/newsroom, 2026/02/xcode-26-point-3-unlocks-the-power-of-agentic-coding, checked September 2026). The same announcement names two agents by name as having direct access inside Xcode: Anthropic's Claude Agent and OpenAI's Codex.

Run this way, the agent works inside the same Xcode window a developer would use: it can ask Xcode to build a target, run a test plan, or read the result of a SwiftUI preview through Xcode's own MCP server, rather than shelling out to a separate command-line build. That keeps the agent scoped to whatever project Xcode already has open, which is a narrower and more predictable surface than a terminal agent free to run any command it chooses.

Terminal agents: building and testing with xcodebuild over the same remote setup

A terminal-based coding agent, the kind covered by the remote AI coding guide or run inside an agent-sandbox VM, does not need Xcode's own MCP server to build an iOS project; it drives the same command-line tool a human developer's CI scripts already use. Apple's own guidance for building outside the Xcode UI describes xcodebuild as the tool for exactly this: performing "build, query, analyze, test, and archive operations" against a project or workspace from the command line (developer.apple.com/library/archive/technotes/tn2339, checked September 2026).

xcodebuild -scheme MyApp -destination 'platform=iOS Simulator,name=iPhone 17' build
xcodebuild -scheme MyApp -destination 'platform=iOS Simulator,name=iPhone 17' test

Over mosh and herdr, that command runs exactly the way any other agent command would in the remote-coding setup: the session survives the laptop sleeping or roaming, and herdr keeps the build running between attaches. An agent's own sandboxing is worth checking too: OpenAI's Codex CLI, for one, documents that it "uses Seatbelt on macOS" to constrain what a command it runs can touch (developers.openai.com/codex/agent-approvals-security, checked September 2026), on top of whatever a Tart VM around it already provides.

The current Xcode, and the macOS it needs

Xcode 27 reached general availability on 14 September 2026 as build 27A266a, alongside iOS 27, and requires "macOS Tahoe 26.6 or later" on Apple silicon only; it does not install on an Intel Mac (developer.apple.com, xcode-release-notes/xcode-27-release-notes, checked September 2026). Its predecessor, Xcode 26.6, still supported Intel hardware, so a build machine set up before September 2026 is worth checking against this narrower requirement.

Apple keeps shipping betas alongside the release, not instead of it: Xcode 27.1's first beta followed the 27.0 general release by four days, adding SDK support for a new device (macrumors.com, 2026/09/18/apple-releases-xcode-27-1-beta-iphone-duo-support, checked September 2026). A machine that also tests against next quarter's SDK before it ships ends up running two Xcode installs side by side, which the storage budget below accounts for.

Continuous integration: a self-hosted runner on the same Mini

An agent that commits its own changes is a reason to run the build and test suite again independently, the way a human contributor's PR would trigger CI. GitHub's own self-hosted runner is the direct option for a Mac Mini already running Xcode: it supports "macOS 11.0 (Big Sur) or later", and the runner application itself "only requires minimal resources" beyond whatever the build needs (docs.github.com, en/actions/reference/runners/self-hosted-runners, checked September 2026). One limit applies regardless of runner: "If you want to run workflows that use Docker container actions or service containers, you must use a Linux machine and Docker must be installed" (same source), so that one workflow step has to run elsewhere.

A self-hosted Git host reaches the same place without GitHub. Gitea's own Actions runner publishes prebuilt macOS binaries directly on its releases page (gitea.com/gitea/runner/releases, checked September 2026); Forgejo, Gitea's fork, ships its own Actions runner too, but its admin guide lists only a binary, a Docker container, or a Linux-distribution package, no macOS build among them (forgejo.org/docs, latest/admin/actions, checked September 2026). GitLab Runner also installs on a Mac, as a background service rather than a system one: "GitLab Runner runs as a user-mode LaunchAgent, not as a system-level LaunchDaemon. This is the only supported mode", with installers for "Apple Silicon or Intel x86-64 systems" (docs.gitlab.com, runner/install/osx, checked September 2026).

Apple's own hosted alternative skips the Mini for CI entirely: Xcode Cloud "is a continuous integration and delivery service built into Xcode and designed expressly for Apple developers" (developer.apple.com, xcode-cloud, checked September 2026), and an Apple Developer Program membership already includes 25 compute hours a month, with paid tiers from 100 hours up to 10,000 a month (same source). A project that only occasionally needs a clean-machine build can live on that quota alone; one building on every agent commit burns through it faster, where a self-hosted runner on the Mini earns its keep.

Why this fills a disk faster than the app's own code ever would

Xcode's own footprint dwarfs almost any iOS project it builds. Measured on a Mac Mini M4 in September 2026: the Xcode 26.6 application itself is 3.5GB; the iOS 26.5 simulator runtime, downloaded the first time a project targets that iOS version, is about 7.9GB, and the watchOS 26.5 runtime for a companion app is about 3.7GB, both read from xcrun simctl runtime list -j. DerivedData, the build cache Xcode writes for every project and rarely clears on its own, had grown to 37GB on the same machine after ordinary use, entirely from build products and indexes Xcode considers disposable but never disposes of itself.

Two more categories have no vendor-published figure and were not present to measure on this machine, so the table below treats them as our own estimate: Archives, the signed .xcarchive bundles Xcode keeps for every build submitted to App Store Connect or exported for ad hoc testing, and device support files, the per-iOS-version debug symbols Xcode downloads the first time a physical device on that version connects. A second full Xcode install, kept for next quarter's beta SDK as the section above describes, costs roughly what the first one does.

What it usesSpace budgeted (our estimate)Left on 256GBLeft on 512GBLeft on 2TB
macOS, a code editor and everyday CLI tools on the host itself40GB216GB472GB1960GB
One installed copy of Xcode (measured on a Mac Mini M4, September 2026: 3.5GB for Xcode 26.6)4GB212GB468GB1956GB
iOS and watchOS simulator runtimes for the platforms actually tested (measured on a Mac Mini M4 via xcrun simctl runtime list -j, September 2026: about 7.9GB for iOS 26.5, about 3.7GB for watchOS 26.5)12GB200GB456GB1944GB
DerivedData, Xcode's per-project build cache, rarely cleared by hand (measured on the same Mac Mini M4, September 2026: 37GB accumulated across projects)40GB160GB416GB1904GB
Archives kept from builds submitted or exported over time (no vendor figure; our own estimate)15GB145GB401GB1889GB
Device support files for the physical devices used to test on (no vendor figure; our own estimate)5GB140GB396GB1884GB
A second Xcode install kept for next quarter's beta SDK (no vendor figure; our own estimate, sized on the measured Xcode install above)4GB136GB392GB1880GB

That is 120GB by our estimate before a single line of the app's own code, its dependencies, or its own build products take any space: 136GB left on 256GB, 392GB on 512GB, 1880GB on 2TB. An iOS project's own repository and its Swift Package Manager or CocoaPods dependencies rarely add more than a few gigabytes on top of that; Xcode's own tooling, not the app being built, is what actually fills the disk.

Cleanup commands worth running on a schedule

Simulator runtimes and old platform SDKs are the easiest part of this to reclaim, and Apple's own developer forums document the commands for doing it without touching a project's own files (developer.apple.com/forums, checked September 2026):

xcrun simctl runtime list
xcrun simctl runtime delete unavailable
xcrun simctl runtime delete --notUsedSinceDays 365
xcodebuild -downloadPlatform iOS

DerivedData has no equivalent built-in prune; deleting the whole folder is safe (Xcode rebuilds it, slowly, on the next build) and is the most direct way to claw back the 37GB measured above. Archives are worth reviewing by hand in Xcode's own Organizer window instead, since each one is a specific signed build that may still be worth keeping.

The honest caveats

  • Xcode 27's Apple-silicon-only requirement is not a future warning, it is the current state: an Intel Mac Mini cannot run the current Xcode at all and is limited to Xcode 26.6 or earlier (developer.apple.com, xcode-release-notes/xcode-27-release-notes, checked September 2026), which will eventually fall behind Apple's own SDK minimums for new App Store submissions.
  • Xcode's built-in MCP server, run through Claude Agent or Codex inside Xcode itself, only works while Xcode is the one running the build; a terminal agent driving xcodebuild directly does not depend on Xcode staying open, which matters for an unattended overnight run where nothing is there to notice if the app quits.
  • The DerivedData, archive and device-support figures above are a snapshot of ordinary use on one Mac Mini M4, not a ceiling: a machine building several projects, or cleaned up less often, will measure higher.
  • A self-hosted CI runner on the same Mini that builds the app is convenient, but it is not a clean-machine guarantee the way a hosted runner or Xcode Cloud is: leftover DerivedData or a half-finished agent session can make a build pass locally that would fail on a genuinely fresh checkout.

Related questions

Do I need Xcode's own MCP server, or is xcodebuild over SSH enough?
Either works, and they solve slightly different problems. Xcode's own agents (Claude Agent, Codex) work inside the same Xcode window a developer would use and can read things like SwiftUI previews directly; a terminal agent driving xcodebuild over the same mosh and herdr setup as any other remote coding session needs no Xcode window open at all, which suits an unattended run better.
Can an Intel Mac Mini still be an iOS build machine?
For now, on an older Xcode: Xcode 27 requires "macOS Tahoe 26.6 or later" on Apple silicon only (developer.apple.com, xcode-release-notes/xcode-27-release-notes, checked September 2026), so an Intel machine is limited to Xcode 26.6 or earlier and will eventually miss Apple's own SDK minimums for new App Store submissions.
Should the agent building iOS apps run inside a sandbox?
The same reasoning as any other unattended coding agent applies: see the agent-sandbox guide for running one inside a Tart VM, Apple's container, or a devcontainer, all of which run on the same Mac Mini M4 as the Xcode install itself.
Do I need GitHub specifically for CI, or does a self-hosted Git host work too?
A self-hosted host works: Gitea's own Actions runner publishes macOS binaries directly (gitea.com/gitea/runner/releases, checked September 2026), and GitLab Runner installs on macOS as a user-mode service as well (docs.gitlab.com, runner/install/osx, checked September 2026). Either can sit on the same Mac Mini M4 that already builds the app, the same way a GitHub self-hosted runner would.
Which capacity should I order for a machine like this?
Work backwards from the table above with the number of Xcode installs, simulator platforms and archives actually kept. The example budget in this guide comes to 120GB, which leaves 136GB free on the 256GB module against 392GB on 512GB and 1880GB on the 2TB module, €399.30. Check which Mac Mini models are compatible first, then see the installation guide for the module swap itself.

Ready to upgrade?

More guides