Published on

The Advantages of Using a Monorepo

Authors

There are differing views about whether or not to use monorepos. For me, like many things, while deving, monorepos are not a one size fits all hammer that treats every situation as a monrepo shaped nail.

I have found monorepos very useful for reasonably small projects where the different components are somewhat coupled to each other. By this I mean for example we have a TODO frontend which is expecting a TODO server API and a DB. If we have separate repos for the UI and for the server it can make finding them in future painful. I have found with previous projects when having separate repos for these app components, it can result in making it much more difficult to find the different pieces in your organization's repo page. You also have to clone each piece and open multiple editors so you can easily reference code in the different pieces.

In the TODO example having one repo that has the UI and server together makes it far easier to find the project and all its pieces. We can now easily point our editor of choice to the root of the monorepo, giving us easy quick access to other pieces of the project.

When I say have the different pieces together I do not mean share code. We would instead have the following repo structure (using the TODO app as an example):

.gitignore
ui
        -> package.json
        -> App.js
        -> .gitignore
        -> ...
server
        -> package.json
        -> Main.js
        -> .gitignore
        -> ...

In the above, I use JavaScript for the UI portion and the server portion but this obviously does not need to be the case. We do not need to worry about merge issues as the ui and server code are separate folders and thus can still be developed in parallel.

Some of the advantages of this setup are:

  • Common Helper Scripts: We could add a makefile or package.json (with scripts) in the root of the project that can be used to streamline the process across both repos.
  • For example:
    • Have scripts to quickly start your server, run some jobs to hydrate the server DB then run the UI.
    • You could have another job that spins up your components in docker when being deved locally or uses the Kubernetes yaml files in each module to deploy the changes to a cluster. This is really useful for CI systems as you simply make them run these scripts instead of having to configure the CI to do this.
  • Code all in one place: Ramp up for new devs on the project will be much faster as you simply point them to one monorepo and let them take it from there. If you have some nice start scripts they simply have to run them and the entire app is running locally. They can then interrogate your other scripts to see what else they can do.

Some of the things you need to watch out for with this setup:

  • Filenames across modules: For example if you are going full stack JavaScript your UI and server folders will both have package.json files. You need to be careful that you do not start mistakenly start editing the wrong file.
  • Common Libraries/Code: If you find you start having to copy-paste pieces inside this monorepo or pull in the monorepo to other projects for a small portion of the code you likely need to move this common code out to a library.
  • Monorepo => Megarepo: The other danger is that people start adding everything to one megarepo.
    • The general rule should be if things in a project change at the same rate then they can live in the same monorepo.
    • Alternatively if things change at totally different rates they should be broken out into their own repos, libraries should be created for common pieces that are used in 3 or more places.