Monorepos were born from pain. Split your code across repositories and it looks clean on paper, but things that should change together start changing apart. Shared library versions drift from repo to repo, one feature scatters into three or four PRs, and the refactor that cuts across everything becomes the refactor nobody dares to touch. So companies like Google put their entire codebase in one tree, and the practice trickled down to ordinary-sized teams through tools like Lerna and Turborepo. Keep together what changes together. That one line is why monorepos exist.
It's why I use one. This blog, its database schema, and an app I built for a friend all live in a single repository, and Turborepo runs the whole thing. But these days most of the code isn't written by me. It's written by agents. Which raises a question that didn't exist before: in the age of AI, where does the monorepo land?
Let me start with the good scenes. A few days ago I moved a database column while adding per-locale cover images to this blog. The schema migration and the app code that reads it live in the same repository, so the change fit in one PR and one CI run verified both. With split repositories, I'd have had one more problem: the deploy order of two PRs. Rules work the same way. The coding conventions live in one file at the root and one per app, and an agent reads the same rules no matter which corner of the tree it works in.
There are bad scenes too. One day my CI bill hit the account spending cap. Counting the runs, a single commit was getting the same checks four times on its way to main. That's less the monorepo's fault than my own for not setting up filters, but it's worth knowing that in a single tree, that kind of mistake multiplies across your neighbors' checks before it lands on your bill. Environment variables burned me once as well. A value was clearly set in the deploy config but never reached the app, and it took a while to find out the monorepo tool's passthrough list was missing that name. One more piece of plumbing to manage, and plumbing tends to fail silently.
The worst one was running several agents in the same repository. Five or six agents were working on top of the same checkout, and when one switched branches, the code under everyone else's feet changed wholesale. The thing being measured changed mid-measurement, and no tool warned anyone. After the same accident six times, I stopped fixing it with rules and fixed it with structure: a separate git worktree per agent, so each one only walks its own tree.
That accident changed how I think about this. What I learned on the sixth round was that the agents weren't the problem. The boundary was. Six humans sharing one checkout talk to each other, so they sidestep before they collide. Agents work fast and silently, and if the boundary isn't drawn in structure, they will step on it.
The monorepo debate itself is old. Hacker News has a post titled Monorepos: Please don't and another titled Just use a monorepo, from 2019 and 2023, each with hundreds of comments. Opposite titles, both persuasive, and years later still no verdict. I think AI just dropped a new weight on the scale. But the weight doesn't land on either side. The real variable is how well you split your AI.
Picture what happens when you can't. Hand an agent the whole repository and the bigger the tree, the more there is to read and the wider the blast radius it can touch. Context windows are finite and trees keep growing, so at some point the agent is flailing under one giant lump. In that state, a polyrepo is better. A physically split boundary is one the agent definitely cannot cross.
But splitting isn't free either. Nx, which sells monorepo tooling, calls this the Memento Problem: every time an agent crosses a repository boundary, its memory resets and someone has to explain everything again. Vendor writing, so read it with salt, but their observation that cross-project changes make up around 20% of commits matches my experience. In a polyrepo, that 20% shatters into as many PRs and deploy-ordering problems as there are repositories involved.
There are remedies, of course, and the lineage is long. There was an era of bots that watched your dependencies and opened a bump PR in every repository the moment a new version shipped. Stitching versions back together across split repositories was exactly their job. But picture the scene: one package bumps, and the same PR gets opened in as many repos as consume it, each with its own CI run. That mitigation got that elaborate is itself evidence the pain was real.
The agent-era remedy has a similar shape. Issue trackers are universal tools, but when your repositories are split, they take on one more role: the conversation channel between repos. I do this myself. When this blog's repository surfaced a problem in the product's repository, I filed an issue there, re-writing the code locations, the measurements, and the options into the issue body. The next session starts by reading that issue, so the memory does carry over. But this is mitigation, not elimination. Writing that issue is itself a cost, and prose doesn't compile, so nobody notices when it goes stale. In a monorepo the same role is played by the code itself, and when it drifts, the type checker catches it mechanically.
Split well, though, and the math flips. If you can make agents carry only what they need, you get the polyrepo's isolation without physically cutting anything, and the monorepo's context stays intact. The cover image work above is the example: the agent read only the app folder and the schema folder, but the two changes could ride one PR because the tree was one. A polyrepo's split is hard to undo once you cut. This kind of split adjusts per task.
That was the logic. I got curious and measured it. I built a small setup — a shared types package and the packages that consume it — in two editions: one monorepo, one set of independent repositories. Same tasks, same agent (Claude Code, same model). And I measured three things: the baseline gap, the effect of tree size, and the effect of change width.
First, the baseline. For a change that cut through three packages — add a field to the shared type, reflect it in the api's math and the web's display — the monorepo took one session at $0.68. The polyrepo took three chained sessions totaling $1.11. The interesting part: output tokens were nearly identical. The actual work was the same, but the polyrepo side read 1.4x the context, because each session had to figure out its repository from scratch and be re-told the previous repository's change as a diff. The Memento cost, captured in numbers. On a local change confined to one package, the two were neck and neck ($0.29 vs $0.33, which I read as noise).
Next, tree size. Same tasks, but I added nine unrelated neighbor packages, growing 3 packages to 12. I wanted to see a reversal. There wasn't one. The monorepo's 40% cost advantage reproduced identically at both sizes, and even in the 12-package tree the agent touched exactly the 3 relevant files. Context cost per turn was flat too (39k vs 36k tokens). Quadrupling the tree had an effect small enough to drown in run-to-run variance.
Last, change width. This time I made a breaking change: Money in the shared types went from a number to an object, and all 12 packages consume it, so nothing compiles until everything is fixed. The monorepo covered all 12 in one session for $0.92. The polyrepo took 12 sessions totaling $4.22. That's 4.6x. And the mechanism is right there in the numbers: the polyrepo sessions cost around $0.35 each with almost no variance, even in repos where the actual fix was one or two lines. What dominates isn't the size of the work but the session's fixed cost — orienting in the repository, reading the diff, re-running verification — and that fixed cost stacks linearly with every repository the change touches. The monorepo pays it once. So the gap isn't made by the size of the tree. It's made by the width of the change: 1.6x when it cuts through 3 repos, 4.6x through 12.
It's a limited experiment, of course. One or two runs per condition, 12 packages is still a small tree, and the diff handoff between polyrepo sessions was done by a script — in real life a human does it, or forgets to, so real polyrepo costs run higher than these. The consumer sessions are independent, so run in parallel the wall-clock evens out — but the cost stays, because the fixed cost follows the session count. And the scenario where an agent drowns in a hundred-package tree is outside this experiment. Still, one thing came through clearly. At this scale, the agent never picked up the tree whole. It found what it needed and touched only that.
This kind of splitting isn't a new idea. People who run monorepos at scale have an old principle: every operation over the repository should be O(change), not O(repo). Builds and tests should scale with the size of the change, not the size of the tree. The agent's context just joined that list. What an agent carries should also be the change, not the repository.
And the tools already point that way. Turborepo reads the dependency graph and skips builds for unchanged apps. CI filters out unrelated checks by path. Worktrees isolate a tree per agent, and rule files layer from root to app. All of it points in one direction: the boundary is migrating from the repository, a physical unit, to the context, a logical one.
I didn't put everything in one tree either. The product, the SDK, and this blog live in different repositories, because I suspected that mixing the producer and the consumer would tempt agents into writing special-case code. Which means that boundary was the same judgment all along: how far does one context reach?
So, will AI settle the monorepo debate? I think it splits on the ability to split. Teams that can't will watch the monorepo become a lump that swallows their agents. Teams that can will find it beats the polyrepo. And if the experiment showed one thing, it's that agents already bring half of that ability with them: in a small tree, mine carried only what it needed, unprompted. The other half — the boundaries, rules, and isolation that keep it true as the tree grows — is what's left for us. The first question is no longer whether to split the repository. It's how much to hand the agent.

Sign in with quickstart.id