Advantages of monorepos
Here’s a conversation I keep having:
Someone: Did you hear that Facebook/Google uses a giant monorepo? WTF!
Me: Yeah! It’s really convenient, don’t you think?
Someone: That’s THE MOST RIDICULOUS THING I’ve ever heard. Don’t FB and Google know what a terrible idea it is to put all your code in a single repo?
Me: I think engineers at FB and Google are probably familiar with using smaller repos (doesn’t Junio Hamano work at Google?), and they still prefer a single huge repo for [reasons].
Someone: Oh that does sound pretty nice. I still think it’s weird but I could see why someone would want that.
“[reasons]” is pretty long, so I’m writing this down in order to avoid repeating the same conversation over and over again.
Simplified organization
With multiple repos, you typically either have one project per repo, or an umbrella of related projects per repo, but that forces you to define what a “project” is for your particular team or company, and it sometimes forces you to split and merge repos for reasons that are pure overhead. For example, having to split a project because it’s too big or has too much history for your VCS is not optimal.
With a monorepo, projects can be organized and grouped together in whatever way you find to be most logically consistent, and not just because your version control system forces you to organize things in a particular way. Using a single repo also reduces overhead from managing dependencies.
A side effect of the simplified organization is that it’s easier to navigate projects. The monorepos I’ve used let you essentially navigate as if everything is on a networked file system, re-using the idiom that’s used to navigate within projects. Multi repo setups usually have two separate levels of navigation — the filesystem idiom that’s used inside projects, and then a meta-level for navigating between projects.
A side effect of that side effect is that, with monorepos, it’s often the case that it’s very easy to get a dev environment set up to run builds and tests. If you expect to be able to navigate between projects with the equivalent of cd
, you also expect to be able to do cd; make
. Since it seems weird for that to not work, it usually works, and whatever tooling effort is necessary to make it work gets done. While it’s technically possible to get that kind of ease in multiple repos, it’s not as natural, which means that the necessary work isn’t done as often.
Simplified dependencies
This probably goes without saying, but with multiple repos, you need to have some way of specifying and versioning dependencies between them. That sounds like it ought to be straightforward, but in practice, most solutions are cumbersome and involve a lot of overhead.
With a monorepo, it’s easy to have one universal version number for all projects. Since atomic cross-project commits are possible (though these tend to split into many parts for practical reasons at large companies), the repository can always be in a consistent state — at commit #X, all project builds should work. Dependencies still need to be specified in the build system, but whether that’s