pnpm and Parcel based monorepo
Tags: javascript, monorepo, parcel, pnpm
Published: 2022-03-13 15:57:16

## The problem

I have tried several ways of managing JavaScript/TypeScript Library Monorepos in the past: `lerna`, `yarn workspaces`, etc.

Now don't get me wrong: These are great tools and I very much appreciate the effort their authors have put into them.

**But they always felt a little bit like gambling.** It never felt like I was really in control of what was happening (with a lot of black magic), and I found that they felt a bit ... fragile (I was alsways worried about breaking some symlinks or stuff like that when running any commands).

## A solution?

I wanted to try both [`pnpm`](https://pnpm.io/) and [Parcel](https://parceljs.org/). I had heard good things about both tools and have recently gotten more and more frustrated with their more established competitors.

When I looked at their respective documentation pages, it looked like both had great monorepo support. Since I was also still on a long-lasting search for some "building an npm library"-compatible monorepo solution with a better developer experience than what I had seen so far, I decided to give it a shot.

## The repository

So, I built (and documented) a test repository to try this new monorepo setup:

{% embed https://github.com/pklaschka/pnpm-parcel-monorepo-test %}

The repository contains a test setup with a more or less full tech stack consisting of, among others:
- TypeScript
- ESLint
- Prettier
- [fliegdoc](https://dev.to/fliegwerk/and-so-i-wrote-my-own-typescript-documentation-generator-2l2f) (a self-built documentation generator)
- jest / ts-jest
- GitHub Actions

I described most things in the `README.md`, but I also created an additional [public Notion page](https://pklaschka.notion.site/Building-and-Publishing-d444abcb209748ec9cea13b9da59bad5#96ee0ded13d54d3eacd18e02de43509f) describing more details.

## Results

**I'm really happy with how it works and will definitely use this approach in the future.** I'll also probably migrate existing monorepos to this approach, in the future.

### Advantages
- :green_circle: **you feel like you're in control** with `pnpm`, it's pretty straight-forward to understand how their workspace system works, so you feel like you're in control and don't have to guess about fixes to your problems :tada:. E.g., `pnpm install` sets up everything. Before, I always was unsure if I should now run `npm install`, `lerna bootstrap`, or something else.
- :green_circle: **quick build times** since `parcel` [builds all the packages at once](https://pklaschka.notion.site/Building-and-Publishing-d444abcb209748ec9cea13b9da59bad5#96ee0ded13d54d3eacd18e02de43509f) (instead of running build scripts one package at a time), build times (especially with the build cache in place) are incredibly fast
- :green_circle: **development experience** with `parcel watch`, it's possible to very quickly develop
- :green_circle: **"native" workspaces** working with workspaces / multiple packages feels "native" to `pnpm` (compared to its competitors, where I unfortunately found that it feels more like a "hacky side feature"). Commands work how I would expect them to work, "internal" dependencies betweeen packages [automatically get hydrated with version numbers on publish](https://pnpm.io/workspaces#publishing-workspace-packages), and so on.

### Drawbacks

Of course, every approach comes with a few drawbacks. Here are the ones I've found so far:
- :yellow_circle: **less ecosystem support** while `pnpm` and `parcel` work great in 99 % of cases, tools often don't test their support for these as much as, for example, for `yarn` and `webpack`
- :green_circle: **(no Dependabot support)** at the time of writing this, GitHub's _Dependabot_ doesn't support `pnpm`. Thankfully, [Renovate](https://docs.renovatebot.com/) seems to work well.
- :green_circle: **(no included "release automation" tooling)** `lerna` came with great Changelog / Conventional Commit / ... based release automation tooling. Unfortunately, I haven't yet found a great solution for doing something similar with `pnpm`. _Do you have any recommendations?_

### A quick fix for a Parcel bug that almost made me dismiss it

When I initially tested Parcel, it felt unstable. It wouldn't shut down, would from time to time just overwrite my `package.json`, and just overall not work very well at all.

I was almost ready to give up when I found [this issue on GitHub](https://github.com/parcel-bundler/parcel/issues/7271). It turns out that I had a `package-lock.json` somewhere higher up the file tree (probably some backup I had created before). This lead to Parcel showing all kinds of weird behavior (not only the one described in the issue). So if you decide to try this approach and feel like Parcel is "freaking out" in a weird way, it might be worth checking for `package.json`, `packaage-lock.json` or similar files higher up in the file tree.

**So overall, this is easy to fix. But this almost made me (which would have been a shame!) turn away from Parcel, so I wanted to include this note here.**

### Even more details

Furthermore, I've documented everything I learned about the process / how the repo is structured in a [Notion Page](https://pklaschka.notion.site/pnpm-and-parcel-for-monorepos-56107d7839594eec8ef5b6d0e9abcb1c). If you decide to try this monorepo configuration, this could be useful to you as it includes all the commands you need to know, links to various important resources, and so on.

## Author

{% user pklaschka %}