The monorepo culture
byKadhir Manickam
(5 minutes)
<section data-section-id='cc19ea37-ba56-4458-aeda-b6f3ec27f79d'><p><span style="white-space: pre-wrap;">At this point, I've read many articles debating between polyrepos and monorepos</span><a href="https://"https://en.wikipedia.org/wiki/Monorepo"" target=""_blank""><sup style="white-space: pre-wrap;"><span>1</span></sup></a><span style="white-space: pre-wrap;">. I've also worked in both setups, many of which I've helped put together.</span></p><p><br></p><p><span style="white-space: pre-wrap;">I've seen what happens when the polyrepo setup gets pushed to the extreme, where every little API and service is in its own repo, inevitably resulting in dependency hell</span><a href="https://"https://en.wikipedia.org/wiki/Dependency_hell"" target=""_blank""><sup style="white-space: pre-wrap;"><span>2</span></sup></a><span style="white-space: pre-wrap;">. But I've also seen what happens when a monorepo becomes so overburdened that the average developer struggles to get the tools to work. All day-to-day development slows down a ton. The tooling to make a monorepo work once you've got even a dozen developers in there is no joke.</span></p><p><br></p><p><span style="white-space: pre-wrap;">Lots of great discussions on the technical trade-offs between these two setups</span><a href="https://"https://github.com/joelparkerhenderson/monorepo-vs-polyrepo"" target=""_blank""><sup style="white-space: pre-wrap;"><span>3</span></sup></a><sup style="white-space: pre-wrap;"><span>,</span></sup><a href="mailto:"https://medium.com/@cfryerdev/monorepo-vs-polyrepo-the-great-debate-7b71068e005c"" target=""_blank""><sup style="white-space: pre-wrap;"><span>4</span></sup></a><sup style="white-space: pre-wrap;"><span>,</span></sup><a href="https://"https://graphite.dev/guides/monorepo-vs-polyrepo-pros-cons-tools"" target=""_blank""><sup style="white-space: pre-wrap;"><span>5</span></sup></a><sup style="white-space: pre-wrap;"><span>,</span></sup><a href="https://"https://earthly.dev/blog/monorepo-vs-polyrepo/"" target=""_blank""><sup style="white-space: pre-wrap;"><span>6</span></sup></a><span style="white-space: pre-wrap;">.</span></p><p><br></p><p><span style="white-space: pre-wrap;">Honestly though, in my experience, the decision between a polyrepo and a monorepo isn't technical; it's cultural. Inevitably, both lead down sort of miserable paths, but I think that's because getting a lot of engineers to collaborate is hard. No getting around that.</span></p><p><br></p><p><span style="white-space: pre-wrap;">Instead, I've been thinking about the cultural implications of each setup and have come to love a monorepo culture. Specifically, one where:</span></p><ul><li value="1"><span style="white-space: pre-wrap;">Development tools are standardized</span></li><li value="2"><span style="white-space: pre-wrap;">There is one release cycle for the entire repo</span></li><li value="3"><span style="white-space: pre-wrap;">Everyone is responsible for keeping main working</span></li></ul><p><br></p><p><span style="white-space: pre-wrap;">So much incredible good happens when those three things are true. And for me, it's all about that feeling of being together, which I've always felt on high-functioning teams. That feeling of our team working together toward shared goals.</span></p><p><br></p><p><span style="white-space: pre-wrap;">Let's dive into some specific aspects of good that I particularly love.</span></p><p><br></p><p><br></p><h3><span style="white-space: pre-wrap;">Engineers can move between projects with less downtime</span></h3><p><span style="white-space: pre-wrap;">The standardized toolkits allow engineers to move between projects without learning a new set of development practices. This results in fewer blockers for management and ICs to cross-pollinate between projects.</span></p><p><br></p><p><span style="white-space: pre-wrap;">When team members can contribute to many initiatives, it's a massive win in my books. I think it feels more like the team is doing something valuable than a specific individual within the team, even if that's true in practice.</span></p><p><br></p><p><span style="white-space: pre-wrap;">In other words, I think the best teams are those where it's tough to identify the source of a good idea. Rather, the idea came about from many interactions and conversations. When engineers can easily contribute to many projects, I think they're more likely to develop interaction patterns that foster natural collaboration.</span></p><p><br></p><p><br></p><h3><span style="white-space: pre-wrap;">Everyone is invested in the development experience</span></h3><p><span style="white-space: pre-wrap;">I have often found the work to improve everyone's dev-x experience underappreciated, but in a setup where everyone shares the experience, it's much easier to understand its impact. May not fix the appreciation problem, but hey, at least people can understand better.</span></p><p><br></p><p><span style="white-space: pre-wrap;">In many ways, this aspect feels like having a shared meal. While eating together is excellent, eating the same foods together is even better. That's an authentic shared experience!</span></p><p><br></p><p><br></p><h3><span style="white-space: pre-wrap;">It's nice to see all the changes in one place</span></h3><p><span style="white-space: pre-wrap;">Seeing all the commits roll in and the systems continually update can be energizing, especially if those changes are reflected in your day-to-day local development experience. You can see how everyone's work is coming together and how it's (ideally) getting better daily, without having to go out of your way.</span></p><p><br></p><p><span style="white-space: pre-wrap;">But more than that, I can point to a concrete, singular code artifact and say I'm a part of that. That's my team, both past and present, represented in code. That's a community I belong to.</span></p><p><br></p><p><br></p><h3><span style="white-space: pre-wrap;">Breaking changes are the responsibility of the author to land safely</span></h3><p><span style="white-space: pre-wrap;">This is the most significant cultural impact for me. In a polyrepo world, I can accidentally introduce a breaking change and publish a minor version bump without realizing it. Then it's on consumers to address the breaking changes when they upgrade. As the consumer, that's such a frustrating experience. Now I'm mad at the author for putting me in this situation! Not good for team camaraderie.</span></p><p><br></p><p><span style="white-space: pre-wrap;">In the monorepo world, it is my responsibility as the writer to ensure that my breaking change lands safely and does not break main. I have a vested interest in either doing the migration myself or getting help from everyone to land my change. Specifically, the onus of completing the migration of the breaking change has moved from the consumer to the author.</span></p><p><br></p><p><span style="white-space: pre-wrap;">Let's go on a tangent for a second and discuss breaking changes that explicitly require consumers to update their code somehow.</span></p><p><br></p><p><span style="white-space: pre-wrap;">Migrating code sucks, especially when you didn't write the breaking change, and even more so when you do not understand why the breaks were necessary. I cannot tell you how many times I have dreaded a major version upgrade to React, ESLint, Prisma, Postgres, etc. The old thing worked great, so do I have to change it?</span></p><p><br></p><p><span style="white-space: pre-wrap;">Well, those changes are necessary for continued improvement. Someone is working to map out a vision for where these things need to go, and they've determined this breaking change is needed. They've done the emotional labor</span><a href="https://"https://greatergood.berkeley.edu/article/item/what_is_emotional_labor_and_why_does_it_matter"" target=""_blank""><sup style="white-space: pre-wrap;"><span>7</span></sup></a><span style="white-space: pre-wrap;"> of figuring out what needs to happen so we can all benefit.</span></p><p><br></p><p><span style="white-space: pre-wrap;">You know what would be even better? If the authors of those breaking changes went around and upgraded everyone! That way, when they come to upgrade my package, I can ask them questions. Now let's tie this back into our monorepo culture.</span></p><p><br></p><p><span style="white-space: pre-wrap;">When an author creates a breaking change, they can go around upgrading all the consumers. When they come to upgrade my package, as a consumer, I can understand why the change is necessary and know the direction they're heading. I can make sure my continued usage aligns with where they're heading. And just as importantly, the author can know how I'm using their package so they can continue to stay aligned to what I need. They're forced to stay close to their customers.</span></p><p><br></p><p><span style="white-space: pre-wrap;">That's a fantastic team interaction right there! It results in better long-term alignment between authors and consumers. Way less frustrating than having something perceived as semi-random, tossed over a fence. I love this! This is an interaction that we can force in a monorepo world.</span></p><p><br></p><p><span style="white-space: pre-wrap;">This is all to say that when debating polyrepos vs. monorepos, I have often found much healthier engineering cultures in the monorepo world that better foster a sense of teamwork.</span></p></section>