What is a Monorepo?
A monorepo is a collection of many different apps and packages in a single codebase.
The alternative setup is called a polyrepo - multiple codebases which are published and versioned separately.
Sharing code
In a polyrepo
In a polyrepo setup, the process for sharing code between applications is relatively lengthy.
Imagine that you have three separate repositories - app
, docs
, and shared-utils
. Both app
and docs
depend on shared-utils
, which is published as a package on npm.
Let's say a bug in shared-utils
is causing a critical issue in both app
and docs
. You'll need to:
- Make a commit in
shared-utils
fixing the error - Run a
publish
task insideshared-utils
to publish it to npm - Make a commit in
app
bumping the version of theshared-utils
dependency - Make a commit in
docs
bumping the version of theshared-utils
dependency app
anddocs
are now ready to be deployed.
The more apps you have that depend on shared-utils
, the longer this process takes. It can be extremely arduous.
In a monorepo
In a monorepo setup, shared-utils
would be in the same codebase as app
and docs
. This makes the process very simple:
- Make a commit in
shared-utils
fixing the error app
anddocs
are now ready to be deployed.
No versioning is required, because app
and docs
don't depend on the version of shared-utils
in npm - they depend on the version that's in the codebase.
This makes it possible to create single commits which fix bugs in multiple apps and packages at once. This can be an enormous gain in speed for teams.
How do monorepos work?
The main building block of the monorepo is the workspace. Each application and package you build will be in its own workspace, with its own package.json
. As you'll learn from our guide, workspaces can depend on each other, meaning your docs
workspace can depend on shared-utils
:
{
"dependencies": {
"shared-utils": "*"
}
}
Workspaces are managed by the same CLI which installs your dependencies.
The root workspace
You'll also have a root workspace - a package.json
in the root folder of your codebase. This is a useful place for:
- Specifying dependencies which are present across your entire monorepo
- Adding tasks that operate on the whole monorepo, not just individual workspaces
- Adding documentation on how to use the monorepo