What is a mono repo
As the name suggests a mono repository has all the code for a solution space in a single source code repository. I use the term "solution space" rather than product or project because there different types of mono repositories. The most extreme examples are at Google and Facebook where they apparently store most of the organisations code in a single repository. Google have published a paper on their implementation and presented on the topic in Why Google Stores Billions of Lines of Code in a Single Repository
Having one source repository does not mean we have to have one monolithic deployable unit. A mono repo will often house many independently deployable services and front end applications. It is therefore compatible with both micro service and majestic monolith designs.
So many packages
The Old Days
Less things to manage, configure and control access to. It also allows us to see the structure of a solution in one place in a single directory structure.
Often in a mono repo development dependencies are hoisted to the top level project thus all packages within the mono repo will share the same version of common dependencies.
Less dev setup
When working with lots of separate repositories we need to configure language and linting rules for every repo. When using tools like typescript there are often shared
In a mono repo we can have one set of compiler settings, linting and code formatting rules that are applied uniformly. If we change a rule we can see the impact and the code is consistent. This also promotes more collaboration around changes in this space.
A local copy of a mono repo may be quite large if there are 1000's of files and a long commit history. At large organisations it could quite easily be larger that your local disk can hold. There are ways around this e.g. retrieving only the latest revision of each file. Google even created their own source control system to deal with this issue.
As the number of deployable projects grows it becomes impractical to deploy everything in the repo on every commit. Some mechanism for detecting and deploying only those project that have changed is required. Unfortunately at the time of writing most CI/CD systems are not able to do this out of the box and some custom scripting will be needed.
Lerna is an opensource project from the babeljs team that makes it easier to manage having multiple nodejs packages in the one repository. Examples of projects doing this include babel (who created lerna), react and gatsbyjs. A larger list exists on the lerna project site.
So what should I do?
As always it depends. Personally I prefer to start with a single repository for a project or product only splitting modules out if they are fairly stable and not directly related to a specific project of product. Something that could be open sourced with distinct value outside of a specific organisation is a candidate for a new repository. I have not worked in an organisation that has only one repo for everything. Even google have separate repositories for angular and chrome.
I think less is more when it comes to setting up build scripts and development dependencies. Also having all the code you need to change for a new feature in one repository mean less messing around with pre-release versions of dependencies and make pull requests easier to understands.
In languages that have stronger type systems having all the code in the same repo makes it easier to detect which compiled dependencies are affected by interface or contract changes.
Here are the links I used writing this post: