Bun workspaces let you manage multiple packages in a single repository (or a monorepo) using the same workspaces field npm and Yarn read. bun install resolves every package in a single pass, dedupes shared dependencies to the root node_modules, and links local packages declared with the workspace: protocol.
For the full configuration reference, see the Bun workspaces documentation.
Set up a Bun workspace
Section titled “Set up a Bun workspace”1. List packages in the workspaces field
Section titled “1. List packages in the workspaces field”A Bun workspace is a repository whose root package.json has a workspaces field listing the directories that hold package.json files. Bun supports full glob syntax here, including negative patterns like !**/excluded/**:
{ "name": "my-workspace", "private": true, "workspaces": ["apps/*", "packages/*"],}2. Add the packages
Section titled “2. Add the packages”Every directory matched by those globs that contains a package.json becomes a workspace package. A common layout separates applications from shared packages:
Directorymy-workspace/
Directoryapps/
Directoryweb/
- package.json
Directorypackages/
Directoryshared-ui/
- package.json
- package.json
3. Link local packages with workspace:*
Section titled “3. Link local packages with workspace:*”To depend on another package in the workspace, reference it with the workspace: protocol so Bun resolves it to the local package. Bun supports workspace:*, workspace:^, and workspace:~, and replaces them with real semver versions on publish:
{ "name": "web", "dependencies": { "react": "^19.0.0", "@my-workspace/shared-ui": "workspace:*", },}Run bun install once at the root to install every package's dependencies and link the internal ones.
Install every package with one bun install
Section titled “Install every package with one bun install”A single bun install at the root installs and dedupes dependencies for all workspaces, so shared packages exist once in the root node_modules. Install speed is the headline Bun feature: per the Bun team's benchmarks, bun install runs up to 28x faster than npm install, which makes full reinstalls in CI and fresh clones noticeably cheaper in a workspace with many packages.
Target packages with --filter
Section titled “Target packages with --filter”The --filter flag narrows both installs and script runs to matching packages. For bun run, place --filter before the script name:
bun run --filter '*' build # run build in every packagebun run --filter web build # run build in a single packagebun install --filter 'pkg-*' # install deps only for matching packagesFilters accept globs and compose: pass --filter multiple times, and prefix a pattern with ! to exclude it, as in bun install --filter 'pkg-*' --filter '!pkg-c'.
How mature are Bun workspaces?
Section titled “How mature are Bun workspaces?”Bun workspaces are the newest of the four implementations. Setup, linking, the workspace: protocol, and --filter cover the everyday workflows, but there's no filtering by dependency relationship or by what changed in git, which the pnpm --filter flag offers. Bun workspaces also have less production mileage overall, and some ecosystem tools expect an npm, Yarn, or pnpm lockfile rather than the Bun lockfile.
If your workspace leans on publishing workflows or unusual install hooks, test those paths before migrating and check the Bun issue tracker for open workspace issues.
Do Bun workspaces replace a monorepo tool?
Section titled “Do Bun workspaces replace a monorepo tool?”No. Bun workspaces make installs fast and link local packages, but they don't cache task results or detect which projects a commit affects, so CI reruns every task on every push no matter how fast the install was.
When that becomes the bottleneck, add Nx on top without changing how Bun works:
npx nx@latest initYour existing package.json scripts keep working and Bun keeps managing installs.
Run tasks before and after Nx
Section titled “Run tasks before and after Nx”Before Nx, Bun runs a script across packages, but it runs every task every time and has no notion of which packages a change affects:
bun run --filter '*' build # every packagebun run --filter web build # a single packageAfter nx init, run the same scripts through Nx:
nx run-many -t build # every projectnx build web # a single projectnx affected -t build # only projects touched by your changesThe first run executes your scripts. A second run with no changes is restored from the cache, and nx affected skips the projects your change does not touch.
Configure caching and dev servers
Section titled “Configure caching and dev servers”nx init writes an nx.json with targetDefaults that control how targets behave:
{ "targetDefaults": { "build": { "cache": true, "dependsOn": ["^build"], }, "dev": { "continuous": true, }, },}cache: true makes a target cacheable: Nx hashes each project's inputs (source files, dependencies, and config) and restores its outputs from the cache when nothing has changed. Nothing is cached unless you opt in, so you stay in control. dependsOn: ["^build"] builds a project's dependencies first. continuous: true marks tasks that don't exit, like dev servers and watchers, so tasks that depend on them don't wait for them to complete.
Speed up CI with Nx Cloud
Section titled “Speed up CI with Nx Cloud”Nx Cloud adds more ways to speed up CI for a Bun workspace: remote caching shares the cache across CI runs and teammates, Nx Agents distribute tasks across machines, and self-healing CI proposes fixes when tasks fail. For the full walkthrough, see Adding Nx to an existing monorepo and CI setup.
Working with a different package manager? See pnpm workspaces, npm workspaces, or Yarn workspaces. New to monorepos? Start with what a monorepo is and why teams use one.