SwiftPM vs CocoaPods on Cloud Mac Xcode CI 2026: Caches, Disk, and a Practical Runbook
Leased Apple Silicon cloud Macs are excellent Xcode CI hosts — until dependency resolution, Pods/ checkouts, and DerivedData silently consume hundreds of gigabytes and your nightly Archive job fails with “No space left on device.” In 2026, most teams still maintain a mixed graph: Swift Package Manager (SwiftPM) for first-party modules and an increasing share of third-party code, plus CocoaPods for legacy pods or binary distributions that never shipped an Package.swift. This guide compares SwiftPM and CocoaPods specifically for remote, shared CI runners (SSH + xcodebuild), maps the cache directories you must back up or purge, and gives a six-step runbook that pairs with our iOS build farm & remote signing optimization article and the GitHub Actions self-hosted runner field guide.
Why Dependency Choice Matters More on Cloud Mac Than on a Laptop
Three patterns break cloud Mac fleets that would “just work” on a single developer machine:
- Shared home directory + multiple schemes — one builder runs three apps; CocoaPods leaves three
Pods/trees while SwiftPM checkouts accumulate under the user cache. Without quotas, the fastest machine becomes the first to disk-full. - Non-deterministic
pod install— bundler/Ruby drift between engineers and CI produces differentPodfile.lockresolutions. Remote debugging over SSH is painful when the failure is “works on my MacBook.” - Binary pods + SwiftPM in one workspace — Xcode integrates both toolchains; clean builds take longer and crash logs reference transient paths under
~/Library/Developer/Xcode/DerivedData.
Pods/) depending on graph depth. A 1 TB node needs scheduled pruning; a 2 TB node buys headroom for parallel nightly Archives.
SwiftPM vs CocoaPods for Cloud Mac Xcode CI in 2026
| Dimension | SwiftPM | CocoaPods |
|---|---|---|
| Native Xcode integration | First-class; packages resolve inside Xcode and xcodebuild -resolvePackageDependencies |
Generates workspace; relies on pod install pre-step |
| CI reproducibility | Strong when Package.resolved is committed |
Strong when Podfile.lock + same Ruby/CocoaPods version pinned |
| Disk footprint on builder | Checkouts under user cache + DerivedData | Full Pods/ tree + possible binaries + DerivedData |
| Clean build time | Often faster incremental when module graph is stable | Can be slower when many pods compile from source |
| Operational complexity | Fewer moving parts on the host | Ruby, Bundler, CDN mirrors, and post_install hooks |
| Best for | New modules, internal libraries, Apple-ecosystem deps | Legacy apps, vendor SDKs shipped only as pods |
Where Artifacts Land: Cache Paths You Should Document
Operations teams that cannot answer “which folder grew overnight?” lose weekends to disk rescue. Standardize these paths in your internal wiki:
| Artifact | Typical location | Notes |
|---|---|---|
| SwiftPM dependency checkouts | ~/Library/Caches/org.swift.swiftpm |
Safe to delete between major upgrades; expect longer next resolve. |
| Xcode DerivedData | ~/Library/Developer/Xcode/DerivedData |
Largest consumer; use per-job -derivedDataPath for isolation. |
| CocoaPods specs & CDN cache | ~/Library/Caches/CocoaPods |
Regenerates from network; watch corporate proxy TLS issues. |
| Project pods workspace | <repo>/Pods |
Should be gitignored; rebuild via pod install. |
CLICOLOR=0 and pin XCODE_XCCONFIG_FILE only when needed — the real win is a documented rm -rf cadence for DerivedData on shared hosts, not endless xcodebuild clean passes that still leave gigabytes behind.
Decision Matrix: When to Prefer SwiftPM, CocoaPods, or Both
| Scenario | Recommendation | Notes |
|---|---|---|
| Greenfield SwiftUI app, no legacy pods | SwiftPM-first | Commit Package.resolved; run xcodebuild -resolvePackageDependencies in CI before compile. |
| Large ObjC codebase with binary Firebase/Segment-style pods | CocoaPods until vendor ships SPM | Track pod sizes; consider splitting CI jobs per app target. |
| Monorepo with shared frameworks | SwiftPM local packages + selective pods | Isolate DerivedData per scheme to reduce crosstalk. |
Open-source forks with scripts in post_install |
CocoaPods | Document Ruby version in .ruby-version and CI image notes. |
Six-Step Runbook for Dependency Hygiene on a Leased Builder
- Pin tool versions — lock CocoaPods via Bundler; for SwiftPM commit
Package.resolvedand fail CI if it drifts. - Pre-resolve in CI — run
xcodebuild -resolvePackageDependenciesand/orpod install --deploymentin a dedicated stage with its own timeout. - Isolate DerivedData per pipeline — use
-derivedDataPath /tmp/dd-$BUILD_IDfor ephemeral jobs or a dated folder you prune daily. - Monitor disk — alert below 15% free on
/System/Volumes/Data; chart growth weekly, not after failure. - Schedule deep cleans — weekly off-peak window: remove stale DerivedData folders older than N days; keep last-known-good caches for default branch only.
- Document rollback — when a bad pod or package version ships, restore lockfiles from git and wipe only the matching cache subtree — not the entire home folder.
Resolution Failures That Look Like “Xcode Is Broken”
| Symptom | Likely cause | Fix |
|---|---|---|
Could not compute dependency graph |
Conflicting SwiftPM + Xcode project settings | Run resolve locally, commit lockfile, clear package cache on CI once. |
CDN: trunk URL couldn't be downloaded |
Corporate proxy / TLS inspection | Mirror specs repo or allowlist CocoaPods CDN hosts on the cloud Mac egress. |
Identical commit, different Pods/Manifest.lock |
Ruby or CocoaPods version skew | Use bundle exec pod install everywhere. |
| Sudden “No space left on device” mid-compile | Parallel jobs on shared DerivedData | Serialize heavy schemes or move to per-job DerivedData paths. |
FAQ: SwiftPM vs CocoaPods on Cloud Mac
| Question | Answer |
|---|---|
| Can I delete DerivedData safely? | Yes — next build is slower. Prefer targeted deletes (per workspace) on shared hosts. |
| Does Apple still invest in SwiftPM? | Yes — new frameworks and sample code default to packages; CocoaPods remains viable for legacy. |
| How does this relate to signing? | Dependency tooling does not fix provisioning — pair with remote signing optimization. |
| Where do I rent a 1 TB or 2 TB Mac mini M4? | Compare regions on pricing and read setup for SSH/VNC defaults. |
Why Mac mini M4 Bare-Metal Nodes Fit Dependency-Heavy CI
Resolution and compilation are both memory- and disk-bandwidth sensitive. Emulated macOS VMs on non-Apple hardware violate Apple’s licensing for iOS builds; nested virtualization on some clouds adds jitter that shows up as flaky SwiftPM network timeouts. A physical Mac mini M4 gives predictable NVMe throughput for massive Pods/ trees and enough unified memory to keep Xcode’s indexer from thrashing when multiple agents run sequentially on the same host.
MacXCode’s pools in Hong Kong, Tokyo, Seoul, Singapore, and the United States let you place builders next to your Git remotes and artifact registries. Combine regional placement with the cache discipline above and you get a boring, repeatable pipeline: resolve once, compile many times, prune on a schedule. Ready to scale? Start at pricing or continue with remote Archive automation.
Cloud Mac mini M4 for Xcode CI & SwiftPM / CocoaPods
1 TB & 2 TB options · HK · JP · KR · SG · US · Bare metal