You should probably use a monorepo

Posted on February 10, 2019

What is a monorepo?

In two of the most recent projects I worked on, the projects initially started out with source code divided into multiple Git repositories. A typical example was having a “shared” or “common” library that was being used both by a frontend and a backend application. Naturally there are many cases where this strict control of dependencies is the correct approach. However, in many projects the additional complexity quickly slows down the team’s velocity. Especially if your team is co-located and working on a greenfield project you have much to gain from bunching up all the source code into a single repository.

This way of managing multiple projects together has come to be called a monorepo. Monorepos are already in use in some large open source projects, such as Jest, React and Angular. One of the most extreme examples might be Google, who is using a single repository to store billions of lines of code in a single repository

What problems might you experience with a “manyrepo”?

  • It becomes very tedious to implement a new feature that needs to change multiple sub projects, especially if you are diligent about doing code reviews before merging code. The amount of time you might spend waiting for another team member to finally have time to review your change to the shared/common repository, in combination with the cost of context switching cannot be ignored.
  • You will need to set up a way to publish and share your code. You might use some form of package repository (cloud based, or on premise). You could use something like Git submodules and Git subtrees (both of which require you to learn new ways of using Git, probably featuring trial and error and painful Git detective work and surgery). You might even write some messy custom shell scripts to manually package and move around tarballs.
  • You will waste time doing “rework” after you forget to update the version number or forget to run your custom distribution scripts.
  • Depending on how you manage depedencies your editor might not easily be able to navigate to functions defined across module boundaries.
  • Your change to a shared module might result in difficult changes needed in part of your application that you didn’t foresee.
  • Doing things like git bisect can be much more difficult in a manyrepo setting.

I definitely recommend you start with a monorepo approach. Especially if you are in a co-located, smaller team, and working on a green field project. You might have to spend a few days beating your head against the wall of how your programming language’s support for a monorepo setup works. But in the long run your increased velocity and lowered frustration levels should be worth it.