Skip to content

[Feature] Support catalog: protocol in yarn add #7081

@literat

Description

@literat
  • I'd be willing to implement this feature (contributing guide)
  • This feature is important to have in this repository; a contrib plugin wouldn't do

Describe the user story

As a monorepo maintainer using catalogs for centralized version management, I want yarn add to
understand the catalog: protocol so that adding or updating dependencies follows the same
workflow as every other dependency operation — through the CLI, not manual file editing.

We maintain a design system with 10+ workspaces and 4 named catalogs (~200 catalog: references
across packages). Every time we need to add a new dependency, the workflow breaks:

  1. Manually add the version range to .yarnrc.yml under the correct catalog
  2. Manually edit package.json to reference catalog:<name>
  3. Run yarn install

This is error-prone (typos in catalog names, wrong version ranges, forgetting to use the
catalog) and feels like a step backward from the otherwise excellent DX that catalogs provide
for existing dependencies.

Describe the solution you'd like

Introduce a --catalog flag for yarn add that:

  1. Adds the resolved version range to the specified catalog in .yarnrc.yml
  2. Sets the dependency in package.json to catalog:<name> instead of a raw version range
  3. If the package already exists in the target catalog, skips updating .yarnrc.yml and only adds the catalog: reference to package.json

Proposed API

# Add to a named catalog
yarn add react --catalog=frontend
# → .yarnrc.yml: catalogs.frontend.react = "^19.0.0"
# → package.json: "react": "catalog:frontend"

# Add to the default (unnamed) catalog
yarn add lodash --catalog
# → .yarnrc.yml: catalog.lodash = "^4.17.21"
# → package.json: "lodash": "catalog:"

# Package already exists in catalog — only adds the reference
yarn add react --catalog=frontend
# → .yarnrc.yml: unchanged (react already defined)
# → package.json: "react": "catalog:frontend"

# Combined with other flags
yarn add eslint --catalog=lint --dev
# → .yarnrc.yml: catalogs.lint.eslint = "^9.39.3"
# → package.json devDependencies: "eslint": "catalog:lint"

# Multiple packages to the same catalog
yarn add react react-dom --catalog=frontend
# → both added to catalogs.frontend and referenced as catalog:frontend

Behavior details

  • --catalog without a value targets the default (unnamed) catalog
  • --catalog=<name> targets a named catalog
  • Version resolution follows the same logic as regular yarn add (latest by default, or explicit
    yarn add react@^18 --catalog frontend)
  • If the package already exists in the catalog with a different version range, Yarn should warn
    and ask for confirmation (or provide --force to override)
  • yarn add without --catalog remains unchanged — no breaking changes

Describe the drawbacks of your solution

  • Adds complexity to the yarn add command — it now needs to write to .yarnrc.yml in addition to package.json and the lockfile
  • The --catalog flag introduces a new optional parameter that interacts with existing flags (--dev, --peer, --exact, --tilde). These interactions need to be well-defined, particularly --exact and --tilde which affect the version range written to the catalog
  • Conflict resolution when a catalog entry already exists with a different range needs a clear UX decision

Describe alternatives you've considered

Why not a plugin?
The catalog: protocol is resolved by Yarn plugin-catalog. A third-party plugin adding a yarn catalog add command would need to duplicate the catalog resolution logic and the yarn add dependency resolution pipeline. It would also fragment the DX — users would need to remember two different commands depending on whether they're using catalogs or not.

Why not a separate yarn catalog command?
A subcommand like yarn catalog add react --name=frontend could work, but it splits the mental
model. yarn add is the established entry point for adding dependencies. Extending it with --catalog keeps the workflow consistent and discoverable.

Manual editing (current workaround)
This is what we do today. It works but it's the only dependency management operation in Yarn that requires manual file editing. Every other operation — add, remove, upgrade — goes through the CLI. Catalogs should not be an exception.


Related: #7048 (closed without discussion), #6400 (original catalog feature request where CLI integration was mentioned but not implemented)

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions