Something I’ve noticed more lately, is this trend of having several npm micro-packages all contained in one repository. Many popular open-source projects adopt this pattern, React, Parcel, Babel, and many more. I would argue that in the majority of cases, this pattern is more detrimental to a project than a benefit, introducing unnecessary complexity at the cost of usability for both the author and the developer.
Why Monorepos?
The idea of monorepos is to ease dependency management. If your project contains a lot of packages that need to depend on certain versions of each other, rather than having them in separate repositories, having them in one place can make it easier to manage them all. Also with one history, these packages will always have commits that are in sync or “atomic”. To make things even easier, there can be custom scripts that can manage the releases of all packages automatically so that there’s never a moment when one package is released without its corresponding package.
A JavaScript monorepo project would typically have this type of structure:
myproject.git/ packages/ package-1/ package.json package-2/ package.json package-3/ package.json ... scripts/ common-publishing-script.js
This is just a small example, but to demonstrate how large some of these monorepos can get:
- React: 32 packages
- Parcel: 81 packages
- Babel: 138 packages
This is absurd in my opinion, and below I’ll explain some of the reasons I’m against the concept of monorepos, and why I believe this is an anti-pattern.
Masking the monolith
There’s several benefits to splitting code into multiple packages, whether it be a library, micro-services or micro-frontends. It results in significantly faster builds, can do independent deployments, and parallelise development across multiple teams, all integrating through an agreed API that everyone can rely on. However, if all of these are hosted in the same repository, you lose a lot of those benefits.