Monorepos, a single code repository used to build multiple discrete projects (like an iOS app and a website), have gained popularity over the past few years. Engineering-led companies like Google, Facebook, and Uber have embraced them as a core part of their infrastructure, triggering a flurry of adoption — even among organizations with smaller development teams. For example, companies like Chef and even FOSSA have adopted monorepo infrastructure for certain projects.
At the same time, some developers have started to push back against the widespread use of monorepos, citing concerns over build pipelines, VCS tooling, and more. (See Matt Klein's blog, Monorepos Please Don’t, for a comprehensive take).
Is a monorepo right for your team? The answer boils down to a strategic architectural choice that influences your engineering culture. It shapes how you collaborate, how you build, and how you maintain code. In this blog, we’ll explore those critical considerations and walk you through some pros and cons of using monorepos.
Pros of Using Monorepos
There are a number of compelling reasons why enterprises have adopted monorepo infrastructure.
1. Better Visibility and Collaboration Across Teams
In a monorepo, all projects are included in the same repository. This means that everyone in a company can see and use code, making shared libraries easier to both discover and leverage. This encourages collaboration and code reuse, which can decrease tech debt.
Because any change to a monorepo can affect the entire company, discussion around technical tradeoffs needs to happen earlier and across multiple teams. Making these strategic decisions up front requires you to be intentional about how you are building, the infrastructure you are using, and how it will work across different components of the company’s software. This often decreases integration costs downstream.
2. Simplified Dependency Management
Monorepos can help simplify internal and third-party dependency management. Referenced dependencies all exist in the same code base, which helps address challenges like the diamond dependency problem and the concern of having multiple projects with multiple versions of the same dependency.
For example, you can pin a specific version of a dependency, making it easier to test for breaking changes and backwards compatibility across your entire codebase when an update is needed. This means that managing vulnerabilities in dependencies is also easier — you only need to patch or update one dependency, making it faster/easier to run unit tests all at once and improving your ability to spot common usages of a shared library.
3. Large-Scale Code Refactoring
This leads to the last key benefit: large-scale code refactoring and atomic commits. Rather than having to make several PR’s across multiple projects to refactor a specific feature like internal APIs, monorepos allow you to address services leveraging the feature with one commit. This accelerates the process from days or even months to a few commits which you can deploy with greater confidence.
For example, we at FOSSA have stored some key projects in a monorepo that consists of several shared libraries used across our products. Moving these to a monorepo greatly improved our process for releasing major changes in how our various systems share logic. Because all of the individual projects were in a single repository, we were easily able to search for a specific method that needed to be refactored instead of trying to remember all the various services that leveraged this method. Overall, this decision has improved team communication and collaboration, decreased our configuration costs, and improved visibility upstream and downstream.
Cons of Using Monorepos
Although a number of engineering-led tech companies have embraced monorepos, there are reasons why many have stayed away. From concerns over access control to the need for additional tooling, here are some of the potential downsides of using monorepos.
1. Build Pipelines
Ensuring your builds are expedient can be a challenge for teams with large code bases. Both Facebook and Google developed their own build tools (Buck and Bazel, respectively) to help manage the build process for their enormous monorepos. Luckily, both Buck and Bazel are open sourced, so you can take advantage of them if you use a monorepo!
I will call out that these build tools are a double-edged sword. Having reproducible builds across a single atomic commit in a monorepo allows you to dramatically improve build performance by caching binary artifacts. This is much harder with multi-repo approaches because you have to build so many more binaries (i.e. all possible version combinations of libraries). Unfortunately, the up-front investment in that infrastructure is quite expensive.
2. VCS Tooling Challenges
VCS tooling can present a couple of challenges as well. Similar to build pipelines, organizations with a large code base and millions of commits may see git performance suffer. Once again, we see that Google created its own customized tooling for this.
Microsoft has released a Virtual File System (VFS) for git to help manage the overload. It allows developers to only download what is needed so they do not have to download the entire monorepo to develop new products and features.
3. Limitations Around Access Control
Access control can also become a problem. There are some instances where your company may not want every engineer to have access to the entire codebase. This also requires planning, coordination, and customization.
Also, it's really hard to open source just part of a monorepo. Starting from a monorepo and pulling out a library you'd like to release as open source is very painful. With multi-repos, open sourcing is relatively less painful because each project is already separated by having multiple repositories in the first place.
4. Open Source Vulnerability Prioritization and Licensing
Although monorepos can make it easier to manage open source dependencies, they may complicate the process of prioritizing vulnerability fixes and generating product-specific attribution reports. You’d need to integrate Software Composition Analysis (SCA) or open source management software with the build system to understand the files and dependencies used to build each product.
Monorepos effectively force you to use monorepo build tools, because most build tools are only designed to handle a single project, and very few existing SCA solutions today integrate with monorepo build tools. Without this data, it would be difficult to determine whether a vulnerability should be prioritized right away because it’s used in a customer-facing product or to generate an attribution notice for a specific application.
Monorepos: The Bottom Line
Ultimately, it would be misguided to view monorepos as either a “good” or “bad” tool for development teams. Instead, it’s clear that there are several compelling reasons why they might help elevate an engineering organization, but also several legitimate challenges associated with their use.
Fortunately, there are tools and strategies that can help teams address some of those concerns. For example, we at FOSSA are exploring new ways to enable teams to better understand and remediate open source compliance obligations and potential security vulnerabilities in their monorepos. Get in touch today for more information.