mirror of
https://github.com/oven-sh/bun
synced 2026-02-02 15:08:46 +00:00
109 lines
4.3 KiB
Plaintext
109 lines
4.3 KiB
Plaintext
---
|
||
title: "Workspaces"
|
||
description: "Develop complex monorepos with multiple independent packages"
|
||
---
|
||
|
||
Bun supports [`workspaces`](https://docs.npmjs.com/cli/v9/using-npm/workspaces?v=true#description) in `package.json`. Workspaces make it easy to develop complex software as a _monorepo_ consisting of several independent packages.
|
||
|
||
It's common for a monorepo to have the following structure:
|
||
|
||
```txt File Tree icon="folder-tree"
|
||
<root>
|
||
├── README.md
|
||
├── bun.lock
|
||
├── package.json
|
||
├── tsconfig.json
|
||
└── packages
|
||
├── pkg-a
|
||
│ ├── index.ts
|
||
│ ├── package.json
|
||
│ └── tsconfig.json
|
||
├── pkg-b
|
||
│ ├── index.ts
|
||
│ ├── package.json
|
||
│ └── tsconfig.json
|
||
└── pkg-c
|
||
├── index.ts
|
||
├── package.json
|
||
└── tsconfig.json
|
||
```
|
||
|
||
In the root `package.json`, the `"workspaces"` key is used to indicate which subdirectories should be considered packages/workspaces within the monorepo. It's conventional to place all the workspace in a directory called `packages`.
|
||
|
||
```json
|
||
{
|
||
"name": "my-project",
|
||
"version": "1.0.0",
|
||
"workspaces": ["packages/*"],
|
||
"devDependencies": {
|
||
"example-package-in-monorepo": "workspace:*"
|
||
}
|
||
}
|
||
```
|
||
|
||
<Note>
|
||
**Glob support** — Bun supports full glob syntax in `"workspaces"` (see [here](/runtime/glob#supported-glob-patterns)
|
||
for a comprehensive list of supported syntax), _except_ for exclusions (e.g. `!**/excluded/**`), which are not
|
||
implemented yet.
|
||
</Note>
|
||
|
||
Each workspace has it's own `package.json`. When referencing other packages in the monorepo, semver or workspace protocols (e.g. `workspace:*`) can be used as the version field in your `package.json`.
|
||
|
||
```json
|
||
{
|
||
"name": "pkg-a",
|
||
"version": "1.0.0",
|
||
"dependencies": {
|
||
"pkg-b": "workspace:*"
|
||
}
|
||
}
|
||
```
|
||
|
||
`bun install` will install dependencies for all workspaces in the monorepo, de-duplicating packages if possible. If you only want to install dependencies for specific workspaces, you can use the `--filter` flag.
|
||
|
||
```bash
|
||
# Install dependencies for all workspaces starting with `pkg-` except for `pkg-c`
|
||
bun install --filter "pkg-*" --filter "!pkg-c"
|
||
|
||
# Paths can also be used. This is equivalent to the command above.
|
||
bun install --filter "./packages/pkg-*" --filter "!pkg-c" # or --filter "!./packages/pkg-c"
|
||
```
|
||
|
||
When publishing, `workspace:` versions are replaced by the package's `package.json` version,
|
||
|
||
```
|
||
"workspace:*" -> "1.0.1"
|
||
"workspace:^" -> "^1.0.1"
|
||
"workspace:~" -> "~1.0.1"
|
||
```
|
||
|
||
Setting a specific version takes precedence over the package's `package.json` version,
|
||
|
||
```
|
||
"workspace:1.0.2" -> "1.0.2" // Even if current version is 1.0.1
|
||
```
|
||
|
||
Workspaces have a couple major benefits.
|
||
|
||
- **Code can be split into logical parts.** If one package relies on another, you can simply add it as a dependency in `package.json`. If package `b` depends on `a`, `bun install` will install your local `packages/a` directory into `node_modules` instead of downloading it from the npm registry.
|
||
- **Dependencies can be de-duplicated.** If `a` and `b` share a common dependency, it will be _hoisted_ to the root `node_modules` directory. This reduces redundant disk usage and minimizes "dependency hell" issues associated with having multiple versions of a package installed simultaneously.
|
||
- **Run scripts in multiple packages.** You can use the [`--filter` flag](/pm/filter) to easily run `package.json` scripts in multiple packages in your workspace, , or `--workspaces` to run scripts across all workspaces.
|
||
|
||
## Share versions with Catalogs
|
||
|
||
When many packages need the same dependency versions, catalogs let you define
|
||
those versions once in the root `package.json` and reference them from your
|
||
workspaces using the `catalog:` protocol. Updating the catalog automatically
|
||
updates every package that references it. See
|
||
[Catalogs](/pm/catalogs) for details.
|
||
|
||
<Note>
|
||
⚡️ **Speed** — Installs are fast, even for big monorepos. Bun installs the [Remix](https://github.com/remix-run/remix) monorepo in about `500ms` on Linux.
|
||
|
||
- 28x faster than `npm install`
|
||
- 12x faster than `yarn install` (v1)
|
||
- 8x faster than `pnpm install`
|
||
|
||
<Image src="https://user-images.githubusercontent.com/709451/212829600-77df9544-7c9f-4d8d-a984-b2cd0fd2aa52.png" />
|
||
</Note>
|