HomeBlogAboutCV
Back to blog

Previous

Should You Modularize Your iOS App?

© 2026 Andre Nogueira

LinkedInGitHubMediumNewsletterXBlueskyMastodonInstagram

The iOS Tool 70% of Developers Prefer — That No Top Company Uses at Scale

April 7, 202617 min read
SwiftSPMTuistBazelArchitectureiOSModularization

This is Part 2 of the iOS Modularization series. Part 1: Should You Modularize Your iOS App?

Table of Contents

  • CocoaPods Is Dead. Now What?
  • The Companies That Didn't Choose SPM
  • The Numbers Don't Lie (But They Don't Tell the Whole Story)
  • Where Is Apple Taking SPM?
  • SPM: Good Enough — Until It Isn't
  • Tuist: The Tool You Haven't Heard Of (But Probably Should)
  • Bazel: Overkill — Unless You're Uber
  • So... Which One?
  • Where to Learn More
  • What's Next

I started writing this article expecting a simple comparison: SPM vs Tuist vs Bazel, pick one, done. Then I looked at what Uber, Spotify, Grab, and Lyft actually use — and none of them picked the tool 70% of iOS developers prefer.

What followed was a rabbit hole: 15 engineering blogs, GitHub issue threads open since 2022, a peer-reviewed academic survey, and Bazel's and Tuist's own documentation. The answer was more nuanced than I expected. Everything here links to its source.

TL;DR: SPM works great until you hit build pain. When you do, Tuist and Bazel solve different problems: Tuist enhances Xcode with caching, project generation, and testing — at any scale. Bazel replaces the build system entirely for hermetic builds, remote execution, and multi-platform monorepos. The choice is about needs, not module count. Jump to the decision framework →

CocoaPods Is Dead. Now What?

If you've been doing iOS development for a while, you remember the pod install days. That era is ending.

A peer-reviewed survey of 112 iOS developers, presented at the IEEE/ACM MOBILESoft 2024 conference, found that 70.5% preferred Swift Package Manager as their primary dependency manager — with CocoaPods at just 26.8%. Another finding: 20.54% had already switched tools, suggesting developers actively evaluate and migrate, not just state preferences.

That's a small sample (112 respondents from communities like Swift Leeds, Cocoaheads Brasil, and the iOS Developers Slack), but the surrounding data tells the same story: CocoaPods officially entered maintenance mode in August 2024. Its spec repository will become read-only in December 2026. Google has announced it will stop releasing CocoaPods versions of its Maps SDK for iOS after Q2 2026.

iOS Dependency Manager PreferenceiOS Dependency Manager Preference

So the survey says SPM. The CocoaPods team says maintenance mode. Google says no more pods. That much is documented.

But then I started looking at who's actually modularizing at scale — and the picture changed.

The Companies That Didn't Choose SPM

I went through every engineering blog post I could find from companies that publicly documented their iOS modularization. Here's what they chose:

Companies Modules ChartCompanies Modules Chart

Note: This chart shows publicly documented module counts from engineering blogs — not tool limits. Tuist has no architectural ceiling on modules, and many companies using these tools don't publish case studies.

These companies chose Bazel. Uber (iOS monorepo, 150+ mobile engineers as of 2017), Spotify (200+ engineers, CI feedback reduced from 80 to 20 minutes), Grab (700+ iOS targets, 2.5M lines of code, 30K+ unit tests), Lyft, Tinder, Pinterest, Discord. All chose Google's build system. Bazel's docs describe the trade-off: steep learning curve and significant infrastructure investment.

These companies chose Tuist. monday.com (~200 modules, CI reduced from 20+ to ~9 minutes), Bumble (110+ modules), Back Market (reported 35-40% faster clean builds), Trendyol (170+ mobile developers across iOS and Android, build time reduced 65%), Qonto (evaluated SPM but chose Tuist, 50% faster builds from modularizing their monolith), Asana, SoundCloud, Etsy, Bending Spoons — Tuist's homepage reports 10K+ teams using the platform, from small teams to large enterprises.

What about SPM alone at 100+ modules? I couldn't find public case studies of companies using SPM as their sole modularization tool at this scale. That's not a verdict on SPM's capabilities — Apple doesn't typically publish case studies about its own tools, and many companies simply don't blog about their build infrastructure. It's an absence of public evidence, not evidence of absence.

What the data does show: SPM is the most popular tool in the ecosystem. The companies that publicly documented their modularization journeys at scale chose Tuist or Bazel — but that tells us more about who writes engineering blogs than about SPM's limits.

That said, there are documented issues. And they're worth understanding before you choose.

The Numbers Don't Lie (But They Don't Tell the Whole Story)

I pulled the GitHub stats for all three projects (as of March 2025).

SPM vs Tuist vs Bazel ComparisonSPM vs Tuist vs Bazel Comparison

SPM has 10,100 stars but 1,045 open issues. Tuist has 5,573 stars with only 197 open issues. Bazel has 25,200 stars with 1,624 issues. These numbers reflect project scope, triage practices, and community size — not quality. A high issue count on a widely-used project is expected.

That said, several of SPM's longest-running open issues specifically describe scalability problems:

SPM Open Issues TimelineSPM Open Issues Timeline

An engineer working on Amazon Flex reported 40-50 minute build increases from transitive dependency resolution in a project with 100+ packages. That issue was opened after talking to Apple engineers at WWDC 2022. It's still open. Three years later.

The Swift Forums have threads about Xcode freezing for 10-15 minutes at the "Packages. Finishing..." stage. Separate reports describe 5-20 second hangs just from adding a file. A SourceKit-LSP issue documents background indexing running 2-3x slower than Xcode's native mechanism.

I've hit this wall myself — scaling a codebase to 50+ SPM modules before migrating to Tuist. The issues in those threads aren't theoretical to me.

But they don't tell you when they start to matter. Before diving into each tool, it's worth understanding where Apple is taking SPM — because that shapes whether these issues will be resolved.

Where Is Apple Taking SPM?

SPM has 9 WWDC sessions across 2018–2025, official documentation on developer.apple.com, and the Swift Package Index indexes over 10,000 packages. No other modularization tool has first-party Apple support.

In February 2025, Apple open-sourced Swift Build — Xcode's internal build engine — acknowledging: "having two different ways to build packages has also led to user confusion when the two implementations' behavior didn't match." The goal: unify how SPM builds code across Xcode and the command-line toolchain. As of Swift 6.3, developers can opt in to test Swift Build as SPM's build system.

Recent Swift Evolution proposals show the direction: SE-0450 (Package Traits), SE-0509 (SBOM generation), SE-0500 (Package Templates). These improve developer experience and compliance — but none address the scalability issues documented in issue #5580. Apple is investing in SPM, but the investment is in breadth, not in the scale problems that push teams to alternatives.

Here's how the three tools compare in community and ecosystem support:

Community ComparisonCommunity Comparison

With that context, let's look at what each tool actually does — starting with what works.

SPM: Good Enough — Until It Isn't

You know this experience: you add a Swift package via Xcode, it resolves in seconds, you import it, and you're writing code. No Podfile. No Ruby. No pod install. It just works.

That experience — zero friction, zero setup — is real, and it's documented. SPM is built into Xcode, maintained by Apple, and the documented scalability issues start appearing at 100+ packages. Below that threshold, I found no public reports of significant issues.

What SPM does well:

  • Zero setup. No toolchain to install, no CI plugins to configure. It's already in Xcode.
  • External dependency management. Adding third-party libraries via Git URL with semantic versioning — production-ready. Replaces CocoaPods cleanly.
  • Local modularization. .package(path:) references give you compiler-enforced boundaries and isolated test targets.
  • Access control. public, package, and internal map directly to module boundaries.

Where it falls short: SPM does cache — Xcode's incremental compilation skips unchanged files via DerivedData, and Xcode 26 introduced a compilation cache using content-addressable storage. This is real caching that delivers incrementality within a single environment. However, it operates at the compilation-unit level — individual file compilations. Cross-machine sharing remains limited as of Xcode 26.0.1. By contrast, Tuist's module cache works at the target level — replacing entire modules with pre-built .xcframeworks and sharing them across machines via remote cache. Tuist's own benchmarks show module-level caching outperforming Xcode 26's remote compilation cache, with build time reductions of 24–77% depending on project structure. Bazel's action cache takes yet another approach: every discrete build step is individually cacheable and shareable, with the option of remote execution that offloads compilation to server clusters entirely. SPM also has no centralized project generation and no way to restrict which targets depend on which. As your target count grows, background indexing degrades — and there's no workaround within SPM itself.

We'll go deep into SPM's hands-on workflow in Part 3. Now let's look at what teams reach for when they hit those issues.

Tuist: The Tool You Haven't Heard Of (But Probably Should)

You switch branches. Xcode hangs at "Resolving Packages." You wait. You clear Derived Data. You wait again. Your .pbxproj has a merge conflict with 47 lines of UUIDs. Sound familiar?

That's the experience that led teams like monday.com, SoundCloud, and Trendyol to Tuist. Their blog posts describe the same pain points — and the same before/after.

Tuist describes itself as a way to "enhance Apple's native tooling." You describe your modules in Swift manifests, Tuist generates Xcode projects. The generated files are disposable — your configuration is the source of truth. Here's what that means in practice:

  • Centralized configuration. Change the minimum iOS version in one file, not thirty. One place for build settings, deployment targets, compiler flags.
  • Project generation. Run tuist generate, get a fully configured workspace. No manual .xcworkspace management.
  • Binary caching. Trendyol cut CI builds from 30 to 10 minutes — and UI test setup from 15 minutes to 30 seconds. monday.com reduced CI from 20+ to ~9 minutes across ~200 modules. Back Market reported "clean builds were faster, up to 35–40% when using third-party dependencies cache, and up to 90% with full cache."
  • Dependency graph enforcement. Feature importing another feature? CI catches it automatically.

The pattern across teams is consistent: monday.com wrote that managing their Xcode project manually "often felt like fighting the tool instead of building with it" — before switching to Tuist. Back Market switched from SPM to Tuist after SPM caused Xcode sluggishness and broken SwiftUI previews. Qonto evaluated SPM but rejected it — and chose Tuist, cutting build times by 50%.

Two features stand out that neither SPM nor Bazel offer:

  • Selective testing. Run only the tests affected by your changes. Tuist ships a native smart runner — Trendyol built their own version before it existed.
  • Stays inside Xcode. Tuist generates standard .xcodeproj files — code completion, debugging, and Instruments all work as expected. Bazel requires Starlark and has limited Xcode integration.

The trade-off: Project generation adds a layer of abstraction — Tuist's own docs acknowledge this. But many of Tuist's newer features — like Test Insights (a post-action on your existing Xcode scheme) and selective testing — plug directly into the existing toolchain without abstracting anything away.

Tuist's homepage reports 10K+ teams using the platform, with 300+ contributors and 8,300+ PRs merged.

Now, Bazel does things Tuist can't. But the reverse is also true — and the trade-offs are steeper than most articles acknowledge.

Bazel: Overkill — Unless You're Uber

Bazel is Google's open-source build system. Unlike Tuist, which enhances Xcode's native tooling, Bazel replaces the build system entirely. Tuist's own docs describe this distinction: some organizations "opt to abandon Xcode's build system and adopt alternatives like Buck or Bazel," but note this "comes with a high complexity and maintenance burden" and "only a few companies with abundant resources can bear this overhead."

What justifies that overhead? Three things that only a full build system replacement can do:

1. Remote execution. Not just caching artifacts — actually running compilation on remote servers. If the cache misses in Tuist, you build locally. If the cache misses in Bazel, a server cluster builds it for you. Spotify reported reducing CI feedback from 80 minutes to 20 minutes this way.

2. Hermetic builds. Two developers build the same branch, same commit, same code — and get different binaries. That's not a hypothetical. It happens whenever builds depend on things outside your source code: system-installed toolchains, absolute paths, different Xcode versions.

Bazel solves this. Its docs define a hermetic build as: "given the same input source code and product configuration, a hermetic build system always returns the same output by isolating the build from changes to the host system." The build downloads its own tools. Every input is tracked by content hash. Same inputs = same outputs, byte-for-byte. This enables crash reproduction (rebuild the exact binary you shipped six months ago), cache reliability, and remote execution (any machine produces the same output). Neither SPM nor Tuist can offer this — both delegate compilation to Xcode's build system, which uses system-installed toolchains and absolute paths.

3. Massive, multi-platform scale. iOS, Android, and backend in one monorepo with a single dependency graph. Grab documents 700+ iOS targets and 2.5M lines of code. Spotify describes 800+ test targets. Square and Mercari both report close to 1,000 iOS modules. Bazel's hermeticity page links to case studies from SpaceX and BMW.

The cost is steep. Bazel uses its own build language (Starlark), requires dedicated infrastructure, and has limited Xcode integration — developers need rules_xcodeproj just to get code completion working. No built-in selective testing, no build insights, no project generation. Spotify's migration went from experimentation in 2017 to full decommission of the legacy build system in 2023 — with 200+ engineers contributing monthly. Uber, Grab, and Lyft had the scale and the dedicated teams to justify it. Most teams don't.

So... Which One?

Three questions to ask yourself — based on what the data shows:

  1. Are you experiencing the documented SPM issues? Build planning freezes, Xcode hangs during resolution, slow indexing? These are the documented triggers that led companies to evaluate alternatives.
  2. Do you need build infrastructure, or a build system? Tuist describes itself as enhancing Apple's tooling — selective testing, build insights, caching, all inside Xcode. Bazel replaces the build system entirely. The distinction is documented by both projects.
  3. Do you need hermetic builds? Bazel's docs define when this matters: remote execution, build reproducibility, and caching reliability. The companies that documented this need — Uber, Spotify, Grab — all operate at hundreds of engineers.

Use this flowchart as a starting point — then check the cost table below:

Tool Decision FlowchartTool Decision Flowchart

Before you commit, consider what migration actually costs your team — based on public data:

SPM Tuist Bazel
Setup time Hours (built into Xcode, no external tools) Days to weeks Months
Learning curve None Moderate (Swift manifests) Steep (Starlark)
Publicly documented scale Up to ~100 packages 200+ modules (no architectural limit) 700–1,000+ modules
CI improvement (reported by teams) Baseline 35–65% faster † 75% faster (80→20 min) ‡
Migration timeline — Weeks to months Years (2017→2023)
Infrastructure None Tuist Cloud (optional) Remote executors, infra team
Xcode integration Native Full (.xcodeproj) Limited (rules_xcodeproj)
Team size Any Any size — small teams benefit too 50+ engineers, 200+ modules

† Tuist CI improvements reported by teams: Back Market 35–40%, Qonto 50%, monday.com ~55% (20+ → 9 min), Trendyol 65% (30 → 10 min). Tuist's own benchmarks show 24–77% build time reduction vs Xcode 26's compilation cache, depending on project structure. ‡ Spotify reported 80 → 20 min with Bazel remote execution.

Note on AI agents (2026): This table doesn't account for the impact of AI coding agents on adoption cost. Tuist ships pre-built skills for agents like Claude Code, Codex, and Amp — covering migrations, project generation, and debugging with a single npx skills install. Bazel has rules_claude, which integrates Claude Code directly into the build system. Both dramatically reduce the learning curve that this table reflects.

If I had to pick one tool for a new project with a team of 15 today, I'd start with SPM — and when build times or project management become painful, I'd evaluate Tuist or Bazel based on what I actually need: Tuist if I want to stay in Xcode with better caching and tooling, Bazel if I need hermetic builds or a multi-platform monorepo. But that's my context — yours might be different.

Where to Learn More

Whatever you choose, you won't be starting from scratch. Here's how the three tools compare at a glance — and the best resources I found for each one.

Tool Comparison: SPM vs Tuist vs BazelTool Comparison: SPM vs Tuist vs Bazel

SPM — Start here:

  • Official Apple documentation — guides for adding packages, creating packages, and managing dependencies
  • Swift.org Package Manager docs — CLI reference and manifest format
  • WWDC sessions — 9 sessions from 2018 to 2025, starting with Getting to Know Swift Package Manager (2018)
  • Swift Package Index — 10,000+ packages indexed, backed by Apple
  • Swift Build open-source announcement — where Apple is taking the build system

Tuist — Start here:

  • Official docs — getting started, project generation, caching, selective testing
  • Migration guides — step-by-step for Xcode projects, Swift packages, XcodeGen, and Bazel
  • awesome-tuist — 86 community resources: 11 talks, 9 videos, 45 blog posts
  • Tuist Slack — active community with maintainers
  • Engineering blogs: monday.com, Back Market, Trendyol, Qonto

Bazel — Start here:

  • Official migration guide — migrating from Xcode
  • rules_apple — community rules for building Apple apps with Bazel
  • rules_xcodeproj — generate Xcode projects from Bazel
  • BazelCon talks — annual conference with 200+ attendees
  • Engineering blogs: Spotify, Grab, Airbnb (Buck to Bazel)

What's Next

I started this article expecting a simple answer. What I found was that the "best tool" depends on a threshold — and nobody had mapped where that threshold actually is.

In the next articles, I'll go hands-on with each tool — code, architecture decisions, migration steps, and the things nobody warns you about:

  • Part 3: SPM in Practice — distribution, local modules, Features + Foundations, dependency rules, and the architecture patterns that keep your graph clean. Where exactly does SPM start to break?
  • Part 4: Tuist in Practice — project generation, binary caching, selective testing, and what teams like Trendyol and monday.com actually changed in their codebases. Includes a full analysis of build time reduction: how module-level caching works, what improvements to expect, and how those numbers are achieved.
  • Part 5: CI/CD at Scale — how to build a pipeline that handles 50+ modules without slowing down your team.

If you're evaluating modularization tools or planning a migration, subscribe below — each article builds on the last, and the implementation details are what save you weeks of trial and error.


All data comes from publicly available sources as of April 2026. Opinions expressed here are my own.

Found this useful? Share it with your team — this is the kind of research that saves weeks of evaluation. Reach out on LinkedIn — I read every message.

Enjoyed this article?

Get the next one delivered to your inbox.

or subscribe via RSS