Code structuring is not a usual subject to discuss when starting a new project. However, it tremendously affects how fast you can make and release changes and the quality of collaboration between developers. In this article, we would like to explore monorepository — a popular way to develop and store scalable projects within a single database.
So what is monorepo, and when to use a monorepo? Let's look closely at the meaning of monorepo to decide why monorepo is bad or good. We'll also compare monorepo vs. multi-repo to help you pick the right approach.
What is a monorepo?
A monorepository or monorepo is a self-explanatory concept: instead of having separate repos (project bases) for each project, you logically group them within a single repo.
There is constant heated talk on monorepo used to structure code, even though monorepos are not a universal approach that fits every project and every team. However, based on our experience, they can significantly benefit project management (if used correctly).
How you store your project services defines how efficiently you will build and manage them. We'll start by looking closely at what monorepos are good at and then consider a few cases in which they're not the optimal choice.
Is monorepo good? It depends on your case. The monorepo approach is only suitable for some types of development projects. Not all teams can tap into monorepo benefits. Here's why and when monorepo may suit your case.
It offers consistency
The repository stays consistent thanks to atomic commits — all project builds will work at any commit. However, you must keep the common history structured by applying tags. Every team member has access to the entire project and can easily track an individual and the general progress.
Simplified dependency management
Why use monorepos? There is no need to specify version numbers for dependencies because there's just one universal version number for all projects. However, keeping different project services tagged is essential not to confuse them.
Easier and more frequent deployment
Both front-end and back-end code are stored in one place. Since you can deploy them simultaneously with a single pull request, deployment takes less time. Engineers can deploy certain services within a project that do not affect other services or the entire project.
Everyone on the team can see the entirety of the project at all times. It allows them to easily identify standard components and share common functionality across monorepo microservices. Yet, the shared access to the whole project can be a concern when the team scales up.
A grep command is all you need to refactor something in monorepos. The restructuring also gets easier and quicker with all code saved in one place. The same relates to the revealing of code duplication.
Faster code review
Reviewing code and tracking changes related to each service and library is simple when everything is neatly stored in one code repository. Such advantages of monorepo optimize the efforts of software engineers, helping them stay on the same page.
Developers can run the whole platform locally and better understand how all services work together, thus finding more bugs. In addition, if the entire code base uses one programming language, a single test runner can check the whole system.
More efficient collaboration
As you establish solid processes on a project, cross-team partnerships and onboarding new team members get much smoother and faster as everyone has full access to all projects and their specifications within a monorepo.
Despite the range of benefits of monorepo, there are also cases when the disadvantages can prevail. Here are some examples of why monorepos are bad.
Access control challenges of monorepos
A monorepo provides the same access levels to engineers involved in a project. Every developer has complete access to the source code of all services and libraries in the mono repository. This can become a significant concern if the number of projects and engineers is extensive, causing security uncertainties.
Development process duration
Building separate services within a single code base can be much more challenging and prolonged than building different projects in different repositories. However, storing all services in one place simplifies project management.
If a project service doesn't work or requires changes, it may affect the delivery of the whole project and the building of other projects within the repository. Also, changes in a specific project part can influence the other services in the repository. Of course, it depends on your CI/CD approaches, but generally, it can cause problems.
Low Git performance in scalable projects
A monorepo is more complicated for Git repository integration than a multi-repo. Issues with specific projects are more complex to track and resolve quickly. That's why teams must tag each issue according to the related service within a project.
Monorepo vs. multi-repo
While monorepos store all project services, libraries, and code within a single codebase, multi-repos offer additional storage for project services. This approach ensures project access where engineers work only in their area of responsibility.
So, what are the differences between monorepo and multi-repo? Let's figure it out further.
All project services and libraries are stored within a single database to which each engineer has shared access
Each project service has its repository where engineers work on it
Enables team collaboration as each developer can see their results within the entire project thanks to shared project access
Each team member sees only a part of the project, with no opportunity to access the overall project.
Teams can quickly reveal code duplication using automated tools
Detecting code duplication may be time-consuming since QAs need to check each repository separately
Simple management as required changes are applied to all projects at once; however, there is a risk of selecting an incorrect service to implement changes
Simple management of projects where services must be strictly separated. But management gets more complicated when there are many repositories
Components shared between multiple services but developed by different teams are easy to manage
Teams need to set the rules for another team of developers to manage shared components
Top cases when you shouldn't use a monorepository
One frequently cited case against a single code repository is that it doesn't scale well. Git performance slows as the number of commits increases and the history deepens. However, this is only true for giant applications and teams with hundreds of developers who work within the same repo daily.
There are a few situations when you should NOT use a monorepo. Here they are:
- For security reasons or otherwise, you don't want everyone on the team to be able to view all the code. There's no way to restrict access to some parts of a monorepo.
- You have many projects, and they're all run by different teams on different technologies. If this is the case, there's no need for the teams to store the entire code base locally.
- There's one part of the code that changes frequently and another part that hardly ever changes. For example, the front-end side of your product changes every month, while everything stays essentially the same on the back-end side. Each deployment risks breaking something (especially if no autotests are in place), and you probably don't want to risk damaging a perfectly functional back-end system. Several monorepo tools provide workarounds, but they're less convenient in this case than having multiple repositories.
We cannot say that a monorepository is a good choice only for small projects. Still, the more services your projects uses, the more complicated project development and management within a single repository is.
All specific benefits aside, a monorepo is ultimately an investment into the team culture. It may be harder to set up at the beginning of your project than having separate repositories, so you should have a few experienced developers who would know what they're doing. As a result, you get transparency and shared responsibility, which is especially important if teams and projects scale.
When multiple repositories have isolated teams working within them, developers don't feel responsible for issues other teams deal with. Within a monorepo, everyone shares responsibility with the rest of the team, so developers have to communicate and collaborate.
And more often than not, monorepos increase productivity and delivery speed, which is a tangible advantage.
Build your development team with Lemberg Solutions
Still unsure which approach to code organization will work best in your specific scenario? Sviatoslav Voitovych, head of business development at Lemberg Solutions, will be happy to help you decide, so feel free to drop him a line.
And if you want to build a team of experienced developers that can help implement your technical solutions, contact our experts to learn more about our services and opportunities for cooperation.
When to use a monorepo for your project?
The monorepo approach is commonly a perfect match for projects that include a small number of services. It simplifies code sharing and refactoring in small teams.
What are the main threats in following monorepo?
The monorepository that combines many different projects complicates some software development processes. Among them are onboarding new engineers on a particular project and Git performance due to extensive information related to various projects. This type of project storage provides no opportunity to set access limits to some projects for different engineering teams.
Should you use monorepos?
The choice depends on the specifics and size of your project, the number of engineers, and the project timeline. Overall, this approach is excellent for small-sized projects with various services that must be collected and easily accessed in one place.