Monorepo tooling
Tags: pnpm, npm, monorepo
Published: 2021-11-30 02:59:41

Last week I found this open [issue](https://github.com/Seneca-CDOT/telescope/issues/1778) from [telescope](https://github.com/Seneca-CDOT/telescope) that peeked my interest. The issue is about improving the [monorepo](https://en.wikipedia.org/wiki/Monorepo) tooling that is used.

Telescope is considered a monorepo because it holds many different projects (in this case "[microservices](https://en.wikipedia.org/wiki/Microservices)") inside one single repository.

Each microservice has its own `package.json` file with dependencies that need to be installed and when we install them all, we end up with many **duplicates** that take up unnecessary space on disk. We can see a list of all of telescope's dependencies [here](https://github.com/Seneca-CDOT/telescope/network/dependencies).

### Looking for solutions

There are different tools to help solve this problem and in this blog post I am going to look at two:

- [npm Workspaces](https://docs.npmjs.com/cli/v7/using-npm/workspaces)
- [pnpm](https://pnpm.io/)

#### NPM Workspaces

npm v7 introduced [Workspaces](https://docs.npmjs.com/cli/v7/using-npm/workspaces): a way to manage multiple packages in a monorepo all from the root directory.

To set it up we need to add this to the `package.json` file in the root of our project:

```json
  "workspaces": [
    "workspace-1",
    "workspace-2"
  ]
```

Now when we run `npm install`, NPM is going to look inside each specified workspace and install the required dependencies.
If possible, the dependencies will be installed in the root `node_modules` folder and then symlinked to the workspace `node_modules` folder to avoid duplicates.

#### PNPM

pnpm stands for **performant** npm and it is in many ways faster than the regular npm. After installing all the dependencies it also uses less space on the disk.

The [docs](https://pnpm.io/motivation) have a great explanation on how pnpm accomplishes this:

> 1. If you depend on different versions of the dependency, only the files that differ are added to the store. For instance, if it has 100 files, and a new version has a change in only one of those files, pnpm update will only add 1 new file to the store, instead of cloning the entire dependency just for the singular change.

> 2. All the files are saved in a single place on the disk. When packages are installed, their files are hard-linked from that single place, consuming no additional disk space. This allows you to share dependencies of the same version across projects.

pnpm can be installed with:
```console
npm install -g pnpm
```

Of course it also supports monorepos. To specify [workspaces](https://pnpm.io/pnpm-workspace_yaml) we can create a `pnpm-workspace_yaml` file with inside:
```yaml
packages:
  - 'workspace-1'
  - 'workspace-2'
```

### Pros and Cons

✅ pnpm is faster and uses less disk space once all dependencies have been installed.

❌ The negative aspect is that it is a new package manager for the user to install and learn how to use.

✅ npm has the advantage of coming bundled with Node, so it is the predominant package manager.

❌ npm, even with its Workspaces improvements, is slower and takes more disk space than pnpm.

---

I have started looking at how to move the Telescope project from using npm to pnpm. I think that if pnpm is not a viable option, npm Workspaces is a good alternative to improve the current way we are doing things.

I will post updates with following blog posts on how this project unfolds!