Monorepos and Workspaces - an introduction
Tags: npm, javascript, webdev
Published: 2022-01-04 01:56:27

**tldr;**
When making a monorepo, it generally consist of workspaces (can use [npm](https://docs.npmjs.com/cli/v7/using-npm/workspaces), [yarn](https://classic.yarnpkg.com/lang/en/docs/workspaces/)or [pnpm](https://pnpm.io/workspaces)), but additional tooling exists like [lerna](https://github.com/lerna/lerna) and [turborepo](https://github.com/vercel/turborepo) (and lots of others too) to help with easing the problems of managing lots of interlinked packages

[see some real world examples](#real-world-use-cases)

### What is a monorepo?
There are lots of other posts that dive into monorepos and their benefits and recommend reading them before diving into the tooling of one. Here is my quick tldr;

> A monorepo is a single repository, that contains multiple loosely coupled packages within it. It differs from a monolith in that it usually has a focus on distributing individual packages, and saves time by allowing multiple changes that might usually need to be made across multiple repository's in a single repository and PR.

#### Further reading
 * https://www.atlassian.com/git/tutorials/monorepos
 * https://css-tricks.com/monorepo/
 * https://medium.com/@mattklein123/monorepos-please-dont-e9a279be011b

## Challenges
It's important to understand the challenges that monorepos present before diving into tooling and weighing up the best suite of tools for your use case.

### 1 - Versioning
The largest challenge people generally face with monorepos managing versions and deployments of packages. One scenario might be that you make a change in one component, bump the version and then want that version to propagate to all the other packages that might depend on it. This is of particular concern for breaking changes as you want to make sure you're not going to break anything for the end users.

### 2 - Deployment and CI
Another challenge can be how to manage deployments, CI. Though a lot of CI tools have functionality to assist with this (e.g. [Github Actions](https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions#onpushpull_requestpaths), [CircleCI](https://circleci.com/developer/orbs/orb/circleci/path-filtering), you may need to think about whether you want to run your CI suite against a single package, or the whole repository, and if any automation might differ depending on the change.

### 3 - PR's
As monorepos can get quite large, figuring out who is best suited for reviews and/or approvals can get a bit tricky. If you use github, adding a [CODEOWNERS](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners) can help with automating this

## Tooling
The below tooling is a list of the most popular tools used for monorepos and managing workspaces. There is not necessarily a magic combination, but rather what works for you and your existing tooling. Not all of these tools are exclusive either, for example, yarn workspaces and lerna can be used together to create a more rich experience.

### Workspaces
Most monorepos in the javascript ecosystem are built upon workspaces, a feature that is now readily available in most of the popular package managers. There isn't necessarily one that is better than the rest and generally follow a somewhat similar syntax pattern, but there may be one that your more comfortable with.

1. [yarn workspaces](https://classic.yarnpkg.com/lang/en/docs/workspaces/)
2. [npm workspaces](https://docs.npmjs.com/cli/v7/using-npm/workspaces)
3. [pnpm workspaces](https://pnpm.io/workspaces)

### Additional tooling
These are optional dependencies that are used to help with deployments, caching and linking packages. There is not necessarily a magic combination, but rather what works for you and your existing tooling.

1. [lerna](https://github.com/lerna/lerna)
2. [turborepo](https://github.com/vercel/turborepo)
3. [nx](https://nx.dev/)

## Real world use cases

### 1 - Component library
One common use of monorepos is a design library. It allows for multiple publishable components and allows for users to import only what they need if desired, and encourages best practices for designing and creating your components by forcing them to be independent entities.

**Example 1 - Chakra UI:** https://github.com/chakra-ui/chakra-ui
**Example 2 - Material UI:** https://github.com/mui-org/material-ui

### 2 - Optional configurations and extras
Another common use case is that a product might have different available options that are made available to the end user, but don't necessarily fit within the core product. This could be using different build tools / versions, different variations of linting or packages that might only cater for specific use cases.

**Example 1 - Storybook:** https://github.com/storybookjs/storybook
**Example 2 - OpenWC:** https://github.com/open-wc/open-wc
**Example 3 - Lit:** https://github.com/lit/lit.dev

## More resources
[list] **[Awesome monorepo](https://github.com/korfuri/awesome-monorepo)**
> Curated list of monorepo resources

[blog] **[11 Great Tools for a Monorepo in 2021](https://blog.bitsrc.io/11-tools-to-build-a-monorepo-in-2021-7ce904821cc2)**
> Probably the best tools to develop and build your monorepo.

[blog] **[What is a monorepo](https://semaphoreci.com/blog/what-is-monorepo)**
> Monorepos can foster rapid development workflows. In this post, we’ll examine if they are the right fit for you and your company.

[blog] **[Trying out npm and yarn workspaces](https://adrianhesketh.com/2021/05/11/trying-out-npm-and-yarn-workspaces/)
> A practical walkthrough of npm vs yarn workspaces