To Love and to Learn (Gil Tayar's Blog)

Scaling the Codebase (Part 4): Wrapping Everything in a Monorepo

greeting card with a 'one' title
photo by photo by Lanty on Unsplash

This is the fourth post in a four part blog series:

  1. Introduction
  2. Modular Code Architecture
  3. Reducing Developer Friction
  4. Wrapping Everything in a Monorepo (this part)

Managing hundreds of packages is not trivial. The standard way of storing package code is one Git repository per package. But when dealing with a modular codebase that has hundreds of packages, this is just not manageable.

The alternative way is a monorepo, where all packages are stored in one large repository, the “monorepository” (or monorepo for short). Each package is a directory in the monorepo. This has some disadvantages:

The advantages of using a monorepo outweigh the disadvantages:

Our monorepo is not an “app” monorepo, and we don’t have a separate monorepo for separate apps. All apps are in the monorepo, with both frontend and backend code together. Visual Studio Code Workspaces enables a developer who is concentrated on one specific app to see only the specific packages they need for that project, so usually our developers are not “lost” in all the packages that are not relevant to their purpose. The folder structure in the monorepo also reflects this. The packages are not put in one big folder, but rather divided into folders based on the project they are in, with a “commons” folder that holds all the packages that are common to all projects.

Lerna #

Whenever we admit that Roundforest uses monorepos, someone invariably jumps up and says that they’re doing monorepos and using Lerna. Lerna is great, and lots of people use it, but it is anathema to a modular code architecture.

The way people use Lerna is, in fact, the opposite of what we’d like to see in a modular monorepo. Lerna enables, and in fact encourages, developers to develop all packages at the same time. By default, Lerna will link all the source code of all the packages, so that changes in one package source code will immediately be applied to all packages that depend on it. Thus, a developer can work on two or more packages at the same time.

Why is this bad? This sounds like a good thing! It’s bad because once you develop packages in tandem, they stop becoming independent:

I like to call Lerna monorepos “project monorepos” or “monolithic monorepos” to differentiate them from the modular monorepo we use at Roundforest. Lerna is good for small-scale monorepos, when you want to generate multiple packages for a single project, and you want to work on all of the packages at once, because they’re published in tandem.

But if you want all the advantages of a modular code architecture, you should avoid Lerna.

Summary #

That’s it! We’ve covered the basics of the Roundforest methodology, and reached the end of the road.

At Roundforest, we pride ourselves on an engineering culture that enables the business to implement changes rapidly, while maintaining the quality of the codebase. We avoid the spaghetti code of rapid changes by using a modular code architecture that enables the code to be split into many independent packages that are easily developed.

This enables the development to be focused, controlled, fast, safe, and frequent, and in general is part of our goal to remove the friction from the development process.

And all this we do in a monorepo, which houses all the company’s code.

(Did you enjoy the series? Check out our open positions here)