import { Tabs, Tab } from "../../../../components/Tabs";

# What is a Monorepo?

A monorepo is a collection of many different apps and packages in a single codebase.

The alternative setup is called **a polyrepo** - multiple codebases which are published and versioned separately.

## Sharing code

### In a polyrepo

In a polyrepo setup, the process for sharing code between applications is relatively lengthy.

Imagine that you have three separate repositories - `app`, `docs`, and `shared-utils`. Both `app` and `docs` depend on `shared-utils`, which is published as a package on npm.

Let's say a bug in `shared-utils` is causing a critical issue in both `app` and `docs`. You'll need to:

1. Make a commit in `shared-utils` fixing the error
2. Run a `publish` task inside `shared-utils` to publish it to npm
3. Make a commit in `app` bumping the version of the `shared-utils` dependency
4. Make a commit in `docs` bumping the version of the `shared-utils` dependency
5. `app` and `docs` are now ready to be deployed.

The more apps you have that depend on `shared-utils`, the longer this process takes. It can be extremely arduous.

### In a monorepo

In a monorepo setup, `shared-utils` would be _in the same codebase_ as `app` and `docs`. This makes the process very simple:

1. Make a commit in `shared-utils` fixing the error
2. `app` and `docs` are now ready to be deployed.

No versioning is required, because `app` and `docs` don't depend on the version of `shared-utils` in npm - they depend on the **version that's in the codebase**.

This makes it possible to create single commits which fix bugs in multiple apps and packages at once. This can be an enormous gain in speed for teams.

## How do monorepos work?

The main building block of the monorepo is the [workspace](/repo/docs/handbook/workspaces). Each application and package you build will be in its own workspace, with its own `package.json`. As you'll learn from our guide, workspaces can **depend on each other**, meaning your `docs` workspace can depend on `shared-utils`:

<Tabs items={['npm', 'yarn', 'pnpm']} storageKey="selected-pkg-manager">
  <Tab>

```json filename="apps/docs/package.json"
{
  "dependencies": {
    "shared-utils": "*"
  }
}
```

  </Tab>
  <Tab>
```json filename="apps/docs/package.json"
{
  "dependencies": {
    "shared-utils": "*"
  }
}
```

  </Tab>

  <Tab>
```json filename="apps/docs/package.json"
{
  "dependencies": {
    "shared-utils": "workspace:*"
  }
}
```

  </Tab>
</Tabs>

Workspaces are managed by the same CLI which [installs your dependencies](/repo/docs/handbook/package-installation).

### The root workspace

You'll also have a root workspace - a `package.json` in the root folder of your codebase. This is a useful place for:

1. Specifying dependencies which are present across your entire monorepo
1. Adding tasks that operate on the _whole_ monorepo, not just individual workspaces
1. Adding documentation on how to use the monorepo
