new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Bun · Package manager · all subjects

workspaces: monorepo structure

24 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

Define workspaces in package.json

In package.json, set the 'workspaces' field to an array of relative paths to define a monorepo workspace structure. Example: 'workspaces': ['packages/*', 'apps/*'].

Root package.json in workspaces should not contain dependencies

The root package.json in a monorepo using workspaces should not contain "dependencies", "devDependencies", or other dependency fields. Each package should be self-contained and declare its own dependencies. It is conventional to declare "private": true in the root package.json to avoid accidentally publishing the root package to npm.

Workspaces field syntax and glob patterns

The "workspaces" field in package.json supports glob patterns. For example, "workspaces": ["packages/*"] treats each subdirectory of the packages directory as a separate package or workspace.

Workspace protocol for inter-workspace dependencies

To add dependencies between workspaces, use the "workspace:*" syntax. For example, to add stuff-a as a dependency of stuff-b, specify "stuff-a": "workspace:*" in stuff-b's package.json dependencies.

Catalogs define shared dependency versions in monorepo

Catalogs share dependency versions across packages in a monorepo. Instead of repeating the same versions in each workspace package, you define them once in the root package.json and reference them throughout your project using the catalog: protocol.

Define catalogs in root package.json within workspaces object

In the root-level package.json, add a catalog or catalogs field within the workspaces object. The catalog field defines a single default catalog, while catalogs (plural) defines multiple named catalogs. Both catalog and catalogs also work at the top level of package.json.

Single catalog syntax and reference

Define a single default catalog using the catalog field with key-value pairs for dependency names and versions. Reference these with the catalog: protocol in workspace packages, which resolves to the exact version specified in the catalog.

Multiple named catalogs syntax and reference

Define multiple named catalogs using the catalogs (plural) field as an object where each key is a catalog name and the value is an object of dependency names and versions. Reference them with catalog:<name> syntax in workspace packages.

catalog: references work in all dependency types

catalog: references work in dependencies, devDependencies, optionalDependencies, peerDependencies, and as the value of a root overrides rule. A catalog reference behaves exactly as if the catalog's range were written inline.

Catalog references must match defined catalogs

Catalog references must match a dependency defined in either catalog or one of the named catalogs. Invalid dependency versions in catalogs fail to resolve during bun install.

catalog:default is equivalent to catalog:

catalog:default is the same as catalog:. You can define the default catalog as either catalog or catalogs.default, but a package listed in both is an error.

Empty strings and whitespace in catalog names treated as default

Bun ignores empty strings and whitespace in catalog names and treats them as the default catalog.

catalog: only works in root and workspace package.json files

catalog: references only work in the root and workspace package.json files. Inside a published package they fail to resolve.

Example catalog and catalogs definition structure

Example with both singular and plural catalog definitions: ```json { "name": "my-monorepo", "workspaces": { "packages": ["packages/*"], "catalog": { "react": "^19.0.0", "react-dom": "^19.0.0" }, "catalogs": { "testing": { "jest": "30.0.0", "testing-library": "14.0.0" } } } } ```

Example catalog references in workspace packages

In workspace packages, reference catalogs with catalog: for default and catalog:<name> for named catalogs: ```json { "name": "app", "dependencies": { "react": "catalog:", "react-dom": "catalog:", "jest": "catalog:testing" } } ```

pnpm workspace configuration migration to package.json

When a pnpm-workspace.yaml file exists, Bun migrates workspace settings to root package.json. The workspaces field in package.json becomes an object with packages (array of globs), catalog (object of version specs), and catalogs (object of catalog groups). Bun moves the workspace packages list and catalogs from pnpm-workspace.yaml to the workspaces field.

Workspaces key in package.json

The "workspaces" key in the root package.json lists the subdirectories to treat as workspaces. It supports full glob syntax including negative patterns such as !**/excluded/**.

Workspace protocol syntax

To reference another package in a monorepo, use the workspace protocol in the version field of package.json. Examples: "workspace:*", "workspace:^", "workspace:~", or "workspace:1.0.2" for a specific version.

Workspace protocol version replacement on publish

When publishing, Bun replaces workspace: versions with the package's package.json version. "workspace:*" becomes the package version (e.g., "1.0.1"), "workspace:^" becomes "^1.0.1", "workspace:~" becomes "~1.0.1". A specific version in workspace protocol takes precedence: "workspace:1.0.2" stays as "1.0.2" even if the current version is 1.0.1.

Local workspace dependency installation

When a package depends on another package in the monorepo using the workspace protocol, bun install installs the local package directory into node_modules instead of downloading it from the npm registry.

Dependency hoisting in workspaces

Bun de-duplicates shared dependencies across workspaces by hoisting common dependencies to the root node_modules directory. This saves disk space and minimizes dependency hell.

Running scripts across workspaces

Use the --filter flag to run package.json scripts in several packages at once, or use --workspaces to run scripts across all workspaces.

Glob patterns in workspaces

Bun supports full glob syntax in the "workspaces" field of package.json, including negative patterns. Example: ["packages/**", "!packages/**/test/**", "!packages/**/template/**"] to include all packages but exclude test and template subdirectories.

Monorepo directory structure convention

A typical monorepo structure has a root directory with package.json, bun.lock, and a packages directory containing individual workspace packages. Each workspace package has its own package.json and source files.

Give your agent this brain