pnpm workspaces or Bazel for a 30-engineer TypeScript monorepo?
CI is now 18 minutes on a green build. Two camps want different futures: pnpm + Turborepo, or migrate to Bazel.
- Ticket
- PLAT-204
- Decider
- VP engineering
- Team
- B2B SaaS, single TS monorepo, 6 apps + 12 shared packages
The blocker
Why this stalled long enough to need a brief.
- CI on green is 18 minutes; on a flaky day it's 35. Engineers are batching commits to avoid waiting.
- Two senior engineers wrote dueling RFCs and stopped reviewing each other's PRs.
- Hiring keeps citing CI pain in exit interviews from the last two leavers.
Options on the table
Each one was a real proposal, not a strawman.
- (a) Stay on pnpm + Turborepo, invest in remote cache + better task graphPicked
Lowest migration cost. Most of the 18 minutes is unnecessary work the task graph already knows how to skip — we just haven't wired remote cache.
- (b) Migrate to Bazel with rules_js
Hermetic, scales to Google-size repos. But: 4–6 month migration, an entire new mental model for every engineer, and the team isn't 300 people.
- (c) Split the monorepo into 3 polyrepos along product lines
Trades CI time for cross-cutting refactor pain. We do 4–6 cross-package PRs per week — splitting would tax exactly the work we want to keep cheap.
The memo
Why we picked Stay on pnpm + Turborepo, invest in remote cache + better task graph.
We pick (a) for one reason: the bottleneck isn't the tool, it's that we haven't enabled the features the tool already has. Remote cache, fine-grained task inputs, and skipping unaffected packages will cut the green build by an estimated 60%.
Bazel is the right tool at 150 engineers, not 30. The migration cost — measured in engineer-months and morale — is real and the payoff is theoretical at our size. We will revisit if we cross 75 engineers or three monorepos worth of code.
Concrete commitments: enable Turborepo Remote Cache by 2026-04-25, add `outputs` and `inputs` to every task by 2026-05-09, and block any PR that takes >8 minutes on green from 2026-06-01. Owner: PLAT team.
What actually happened
Followed up roughly 30 days later.
Remote cache shipped 2026-04-23. Green CI median dropped from 18 minutes to 6 minutes 40 seconds within a week.
The 'fine-grained inputs' work is two-thirds done; the long tail is one legacy package that codegen-bombs every PR. Tracked in PLAT-217.
The two senior engineers are reviewing each other's PRs again. The decision being written down — and the loser being heard in the memo — mattered more than the technical content.
The other doors
The arguments we didn't take, preserved.
- (b) Migrate to Bazel with rules_jsHermetic, scales to Google-size repos. But: 4–6 month migration, an entire new mental model for every engineer, and the team isn't 300 people.
- (c) Split the monorepo into 3 polyrepos along product linesTrades CI time for cross-cutting refactor pain. We do 4–6 cross-package PRs per week — splitting would tax exactly the work we want to keep cheap.