Benefits and challenges of monorepo development practices
Senior Manager, Marketing Insights and Strategy
In this article, you will learn what a monorepo is, the benefits and challenges of adopting it as a version control strategy, and how to decide if a monorepo is right for your organization.
What is a monorepo?
A monorepo is a single, centralized storage repository for all your application and microservice code. Unlike traditional, decentralized version control strategies where each project or service has its own repository, a monorepo encompasses the entire codebase in one repository. This includes libraries, services, and sometimes even datasets and configuration files.
Using a platform like Git, a monorepo can simplify development by streamlining code organization and automated processes. This setup boosts visibility, encourages collaboration through shared code and common tooling, and promotes consistent coding practices across teams. Viewing all code together in a single repository also improves tracking changes, resulting in better release management and smoother code updates.
Monorepos typically have a single build pipeline that produces the application executable. Teams often structure code for different app components into subfolders and use Git workflows for adding features or fixing issues. This straightforward approach is common for applications with a monolithic design, but it can slow down development if a few hard-to-fix bugs stop deployment of release candidates to production.
Monorepo vs. polyrepo for microservices
As microservices architecture becomes more popular, many teams choose to split their code into multiple repositories (polyrepos), each corresponding to a specific microservice. Developers work on microservices independently, using different, problem-specific tools and programming languages. For example, some developers may use open source projects like Python for artificial intelligence (AI), while others use Java or .NET to implement APIs.
The advantages of polyrepos are clear. A small team can rapidly implement, and independently deploy, a microservice for high-velocity software development. But the polyrepo approach can quickly become difficult to manage as the number of microservices grows.
Separate repositories introduce risk
At some point your team could discover that system knowledge is spread across multiple repos maintained by different teams. You may realize that no one knows how to build and deploy the entire system. Tooling and configuration conflicts can cause bottlenecks, and automated builds and deployments may slow as complexity increases.
Although polyrepos seem to be the natural choice for microservices, a monolith with unified and automated build and deploy pipelines can mitigate many issues. A closer look at the benefits of monorepos — and some of the misconceptions — may help you decide if a this kind of environment is best for your team.
Benefits of monorepos
There are several advantages to adopting the monorepo approach:
- Easy visibility. If you are working on a microservice that calls other microservices, you can look at the code, understand how it works, and find out if bugs are from your own code or another team’s microservice.
- Code sharing. Teams duplicating code for microservices create additional engineering overhead. If common models, shared libraries, and helper code are all stored in a single repository, teams can share them among many microservices.
- Improved collaboration. A monorepo removes barriers and silos between teams, making it easier to design and maintain sets of microservices that work well together.
- Standardization. With monorepos, it is easier to standardize code and tooling across the teams. You can create policies that keep your main branch uncluttered, limit access to specific branches, enforce naming guidelines, include code reviewers, and enforce best practices. Branch policies keep in-progress work isolated from completed work.
- Discoverability. A monorepo offers a single view of the whole codebase. You can review status for the entire repository, screen all branches, and keep track of modifications much more easily in monorepos than in polyrepos.
- Release management. A monorepo retains all the information about how to deploy the whole system. An automated build and deploy pipeline doesn’t hide deployment knowledge within each team the way it does in a polyrepo.
- Easier refactoring. Direct access to all microservices makes it easier to refactor the code in a monorepo. Also, you can change the code structure. Moving the source code between folders and subfolders is much easier than moving the source code between multiple repositories.
Challenges of monorepos
Despite these benefits, monorepos create several challenges. Changing a common code can impact many application components, and the source conflicts can be difficult to merge. Your deployment process can be more challenging, and you must be able to scale your source control management system.
But, depending on your situation, the benefits of monorepos may outweigh these challenges.
Misconceptions about monorepos
If you have been developing apps in microservices architecture, you may have some misconceptions about monorepos. Let’s explore a few common examples below.
Misconception 1: Monorepos must use a single set of languages and tools
Some developers think that multiple programming languages and tools prevent using a single repo due to difficulties in creating the uniform build process. You can mitigate this by using containers, with each microservice built into the container image, and then deployed as an individual unit.
Once you have containerized microservices, you can also test them individually. So, instead of keeping all the build stages in many repositories, you can keep them in the monorepo. The only difference is that your build target is set to containers.
Misconception 2: Monorepos result in tightly coupled code
Often, developers think monorepos cause tightly coupled code. Not really, but you must exercise good judgment to prevent turning code into a tangled mess.
When developing microservices, you make them independent, so they don’t rely on other microservices. You can do the same in a monorepo when your team follows best practices and guidelines for microservice development.
The idea is to split a big system into independently deployable, loosely-coupled units that, unlike components, communicate with each other over the process boundaries (typically using REST APIs). Though the monorepo makes it easy to break microservice architecture patterns, it does not cause tightly-coupled code by itself.
Misconception 3: You cannot update services independently in a microservice
You may think updating microservices independently is impossible with a monorepo. It’s not. You can meet this challenge by replacing rolling updates with more advanced deployment strategies, like blue-green or canary. You can deploy the new version side-by-side with the previous version while you ensure the new microservice version works as expected. If you detect a bug, you can quickly redirect traffic to the previous version.
Managing monorepos with CI/CD
Automated continuous integration and continuous deployment (CI/CD) pipelines help mitigate common monorepo challenges. Each development team can independently work the microservice, build its container image, and deploy it without affecting other teams. They can validate the microservice in a test environment before sending it into production, and keep both the old and new versions available. Containerization lets you deploy and test microservices independently without worrying about their different tools and programming languages.
CI/CD tools can scale automatically and help you manage complex deployments so that you can build, test, and even deploy individual microservices from within a larger monorepo.
Deciding if a monorepo is right for your team
How do you decide whether to use a monorepo or polyrepo for your microservices development? First, assess your team’s culture. is it a good fit for the collaborative development a monorepo encourages?
Second, assess your team’s discipline. Will they be able to refrain from creating tightly-coupled code? They need to avoid making their microservices dependent on other microservices in the monorepo. Remember, you can enforce this discipline with branch policies and permission restrictions that control who can deploy microservices to production. Permissions determine which teams and team members can deploy each service.
You can put all these practices into place with a unified, automated CI/CD pipeline where your team builds, tests, and deploys individual microservices from within the monolith. Automating your pipeline makes it easier to manage your monorepo while keeping up your rapid deployment pace.
Conclusion
Monorepos provide benefits like visibility, collaboration, and code sharing, but they are not the right fit for every team. Understand your team’s strengths and weaknesses to decide if a monorepo is the right choice.
If you decide to use a monorepo, maintain your high-velocity software deployment and mitigate common microservices pitfalls with a unified and automated CI/CD pipeline. You can get started right away, by signing up for a free CircleCI account today.