Skip to main content

To monorepo or not to monorepo: that’s the question!

22 September 2022

Photo by Camille Villanueva on Unsplash

Mono from Ancient Greek μóνος, read mónos, means “alone, only, sole, single”.

Repo short for repository, is a version control system unit for storing software source code and metadata.

Monorepos have been around for a while, and they have become a standard for open-source projects. Although they were used widely before, they were not so widely used as in the last decade or so, especially after Facebook’s single repository was 54 GB big and Google declaring its One Version Rule for third party libraries, as well as announcing summing up 86 TB about eight years ago.

These stories, while fascinating, are daunting, if not downright scary.

So, what’s all this monorepos buzz about and why is it so popular?

To understand the value of something one must first understand the problem it is trying to solve. And it is known that, in Computer Science, a problem can have multiple solutions, while at the same level, one solution might solve multiple problems. But let’s take a different approach.

There is a lot of incredible stuff about monorepos out there, which would be unfair not to quote and or even try to replicate, so, instead, I’ve compiled a couple real life examples of when a monorepo would have been a life-and-project saving decision and also when it shouldn’t have been used.

To assist us, we’ll use Alice and Bob, borrowed from the cryptography greats Rivest, Shamir, and Adleman.

When monorepos would have been a life-and-project saver

Photo by Barn Images on Unsplash

Bob and Alice own company’s shared tooling

Bob and Alice had an internal company project that would benefit from contributions from whomever ended up using it. The premise was awesome and the expectation of doing open source for a closed community was sky high.

Many packages ended up being created and the project rapidly required maintenance over a dozen version-controlled repositories and manifests.

It didn’t take long before dealing with version updates, version pairing with other packages and circular dependencies became an issue. Maintenance became a burden.

Had Bob and Alice used monorepos, where all packages are kept in the same source-tree, and the dependencies versions are all listed and in a single manifest, then they would have freed up valuable time, as well as company resources.

Bob and Alice build a community-driven project

Bob and Alice were building a web app’s framework for the open-source community. They set up a repo for it and got it working in no time. Then it was time to set up samples and demo projects, and eventually a scaffold generator. Suddenly, as with their previous experience, maintaining multiple repositories, with a good deal of issues being registered and changes suggested, became cumbersome and responding to all the requests even more daunting because if the framework changed then:

  • samples must reflect the change
  • generator must reflect the change
  • documentation has to be updated

While everything must be linked and tested before release and the community effort was only for the framework, updating everything else was Bob and/or Alice’s responsibility. Releases rolled out long after the patch was created. Community started to fade away to other solutions.

A monorepo, like in the previous story, could keep everything under the same project, making it easier to contribute to and to delegate that a change must reflect in other areas of the project without going over different repositories. Community would be engaged, and Bob and Alice would be regarded as leaders of that framework.

When monorepos could be a hurdle

Bob builds a proof of concept for Alice

Simplicity should always be the ultimate goal, and a monorepo setup is far from that.

Alice requires a proof of concept to decide which framework to use to build an e-commerce app, with some of the frameworks written in different programming languages. Bob decided to think ahead and started scaffolding a monorepo for all probed technologies. No automated build pipelines were required, nor was a code coverage threshold imposed. No shared code was required.

Getting the tooling right for all the implementation samples always takes considerable time, not to mention which tool, since multiple languages have tooling for monorepos.

The lack of pragmatism led to an underestimation of the Proof of Concept (PoC) and an inflated result. Bob was saddened by the result and the main research objective — which tool for building a storefront would be faster to develop with - was a total swing-and-miss.

Often PoCs haunt us as they serve as the foundation for future projects. Investing in the tooling and scaffold before an actual plan develops into that dreaded path.

Photo by George Nifakos on Unsplash

Bob and Alice want one repository for everything

Alice and Bob were using a monorepo setup while on two different projects, and it worked well for some time, proving to be a wise choice. However, the project had some requirements, such as reporting, testing, and documentation, where Alice and Bob had different views and ideas for those requirements.

Alice and Bob sat and broke bread many times to decide which tools to use for those requirements, although quorum was seldom achieved without compromise.

Teams started to feel powerless over which tools to use for their developing needs, and leaders took a more oppressive standpoint in terms of ownership. The dependency graph started to grow sideways, building times increased, and collaboration decreased.

While having everything under the same repository may sound appealing, it is wise to understand that what should live on that repository should be well-defined. A domain for a project is seldom the project itself, but a collection of domains. And many organizations require control, such as access management, over those domains, which, by packing it all together, is hard to achieve.

Afterthought

All in all, it’s hard to go wrong when adopting a monorepo approach, despite its imposed conventions and learning curve. It’s a decision that bears fruit very quickly, such as making it easy to modularize projects while increasing code reusability. Hence, strengthening acronyms like Don’t Repeat Yourself (DRY) and Domain-Driven Design (DDD), and applying strategies like divide and conquer.

A monorepo structure also eases standardizing the tooling across different applications and libraries, increasing predictability, which decreases the need for such a thorough documentation that is always a hard sell in the enterprise world. Testing also becomes easier, since modularization is the key, and the smaller the unit, the easier it is to test it.

There are many monorepo-compatible tools out there. Some are tooling rich, such as Nx and bazel. Others are more spartan, such as the widely used NodeJS’ package managers, offering only the folder structure, dependency and versions management, such as yarn, pnpm, or even npm itself on the more recent versions, and leaving to the developers what to use for the everyday tasks.

There are always caveats when adopting these strategies, but at the same time, nobody would put in the work to build them if they weren’t fixing a problem, nor they’d rise on the trends’ ladder if they weren’t useful.

On a personal note, I haven’t prototyped anything without, at least, using the workspaces solution from the aforementioned package managers, with the sole motive of easy module portability and reusage, and standardization of the tooling and day-to-day commands.

It feels like the next stage of evolution, just like when package managers became standard for managing projects’ dependencies and aliasing the run and build commands.

At craftable, we develop boutique software always on top of the latest architectural concepts for all our nearshore projects. Get to know our software house or visit us at our offices in the lovely cities of Porto and Aveiro!


To monorepo or not to monorepo: that’s the question! was originally published in craftable on Medium, where people are continuing the conversation by highlighting and responding to this story.