Why we moved to a monorepo
How consolidating code into a single repo improved our velocity and DX.
For the first two years, our projects lived in separate repositories. This felt right — clean separation of concerns, teams that could move independently, no risk of one project's dependency upgrade breaking another. The cracks appeared gradually, then all at once.
The immediate trigger was a shared UI library. We had the same component suite duplicated across four separate repos, with four separate versions diverging in subtle ways. A bug fix in one never propagated to the others. A design token change required four pull requests, four reviews, and four deployments — and they still didn't stay in sync.
Moving to a monorepo solved the library problem immediately. One commit updates the component for every consumer simultaneously. Type contracts between packages are checked at CI time, not discovered at runtime. The feedback loop on cross-package refactors collapsed from days to minutes.
The tooling investment is real. We use Turborepo for task orchestration and caching. Getting incremental builds right took a focused week of configuration work. But that investment paid back within the first month — CI times on a full build dropped by over sixty percent because unchanged packages simply aren't rebuilt.
The cultural shift is underrated. When all the code is in one place, context-switching between projects gets cheaper. Engineers stop thinking in terms of repo ownership and start thinking about the system. Junior engineers especially benefit — they can trace a behaviour from the frontend all the way to the database schema without jumping between repos.
Key Takeaways
- Shared libraries are the main forcing function for monorepos
- Turborepo caching cuts CI times dramatically for large workspaces
- Cross-package type safety catches integration bugs at compile time
- Monorepos reduce context-switching cost for engineers across projects
Zerguine Abdelbasset
PerceptronDev Team
