← How we think

macOS runners and why they work differently

We can build iOS apps. But the model is fundamentally different from Linux, and here is why. Windows is not on the roadmap.

Linux: shared, isolated, cheap

gittan's Linux runners run every pipeline step inside a container. Each build gets its own filesystem, process namespace, network, and secrets. Two builds from different organizations can run on the same machine at the same time without any risk of interference. This is what makes shared runner pools possible — and what keeps the cost low.

Container isolation is a kernel-level guarantee. It is not a convention or a best practice — it is an enforcement boundary that the build cannot escape. This is why gittan can offer Linux pipelines without per-minute billing and without dedicated infrastructure per organization.

macOS: no containers

Apple requires Xcode to build iOS and macOS applications. Xcode runs only on macOS. There is no cross-compilation path for Swift or Objective-C targeting iOS — Apple has locked the toolchain to their operating system.

macOS does not have Linux-style container isolation. There are no kernel namespaces, no cgroups, no filesystem overlay. A build runs directly on the host operating system. That means:

  • ‣ Builds can read files left by previous builds on disk.
  • ‣ Signing certificates and provisioning profiles live in the system Keychain.
  • ‣ Environment variables from one build could leak to the next without careful cleanup.
  • ‣ There is no way to enforce resource limits per build at the kernel level.

Container engines can run on macOS — they start a Linux VM via Apple's Virtualization framework and run containers inside it. This works for orchestration, but the Xcode build step itself must execute natively on the Mac. The isolation boundary that makes Linux runners safe to share between organizations does not exist.

One node per organization

Because there is no container boundary, macOS runners cannot be shared between organizations. Each organization gets a dedicated Mac — a physical machine that only runs that organization's builds. This is not a limitation we chose. It is a consequence of how macOS works.

Within an organization, builds from different teams run on the same machine sequentially. This is consistent with gittan's trust model: organization members can read all repos in the org. Cross-team within the same org is not a security boundary for build artifacts.

What this means for pricing

Linux runners are a shared pool. The cost is spread across all organizations, and the marginal cost of one more build is effectively zero. This is why Linux pipelines are included in every plan.

macOS runners are dedicated hardware. A Mac Mini sits in a data center, allocated to one organization, running or idle. The cost does not scale with usage — it is a fixed monthly fee regardless of how many builds you run. This makes macOS runners a paid add-on, not an included feature.

For teams that build frequently, this is significantly cheaper than per-minute pricing. A single Mac Mini can handle dozens of builds per day. For teams that push rarely, the fixed cost may not be worth it — the break-even point is roughly 1.5–2 hours of build time per day compared to per-minute alternatives.

What we support today

macOS runners are not available yet. Today, gittan runs all pipelines on Linux using containers. This covers the majority of build workloads, including Android builds (Kotlin, Java, KMP), cross-compiled desktop applications, and server-side Swift.

iOS and macOS application builds that require Xcode are on our roadmap. When we ship macOS support, it will be a managed offering — gittan provisions and maintains the hardware. We will not offer a bring-your-own-runner model, because we cannot guarantee pipeline speed, security, or reliability on infrastructure we do not control.

Android works today

Android builds do not require macOS. The Android SDK, Gradle, Kotlin compiler, and all KMP tooling run on Linux. If your team builds Android apps, they work on gittan's existing Linux runners with full build caching — no special configuration, no dedicated hardware, no per-minute cost.

Windows is not on the roadmap

gittan does not offer Windows runners and has no plans to. The workloads that historically required Windows to build — .NET Framework 4.x, MSI installers via WiX, UWP apps — are legacy. Modern .NET (6+) cross-compiles from Linux with dotnet publish -r win-x64. Electron and Tauri build Windows binaries from Linux. WPF and WinForms on .NET 6+ cross-compile too.

If your application targets Windows, the build almost certainly runs on Linux today. If it does not, it is because the toolchain is legacy — and the right move is to migrate the toolchain, not to build infrastructure around it.