Skip to content

toss/yarn-plugin-catalogs

Repository files navigation

yarn-plugin-catalogs

A Yarn plugin that manages catalog definitions in catalogs.yml and delegates to Yarn's native Catalogs support (available since Yarn 4.10.0).

Highly inspired by pnpm Catalogs.

Why use this plugin?

Since Yarn 4.10.0, Yarn natively supports catalogs for managing dependency versions across your workspace. This plugin extends Yarn's native support by:

  • Managing catalogs in a separate catalogs.yml file for better organization
  • Supporting hierarchical catalog inheritance (e.g., stable/canary inherits from stable)
  • Providing validation to ensure consistent catalog usage across workspaces
  • Auto-applying default catalogs when adding dependencies

Requirements

  • Yarn 4.10.0 or later (for native catalog support)

Installation

yarn plugin import https://raw.githubusercontent.com/toss/yarn-plugin-catalogs/main/bundles/%40yarnpkg/plugin-catalogs.js

Usage

1. Create catalogs.yml in your project root

# catalogs.yml

options:
  default: [stable]  # Optional: Default catalog groups for 'yarn add'

validation:  # Optional: Workspace-based validation rules
  - workspaces: ["*"]
    rules:
      catalog_protocol_usage: warn

list:
  root:  # Special alias for the root catalog (accessed via catalog:)
    lodash: npm:4.17.21

  stable:
    react: npm:18.0.0
    typescript: npm:5.1.0

  stable/canary:
    react: npm:18.2.0  # Overrides stable

  beta:
    react: npm:19.0.0

2. (Optional) Configure schema validation in VSCode

For better editing experience with catalogs.yml, you can enable schema validation in VSCode by adding the following to .vscode/settings.json:

{
  "yaml.schemas": {
    "https://raw.githubusercontent.com/toss/yarn-plugin-catalogs/refs/heads/main/sources/configuration/schema.json": "catalogs.yml"
  }
}

This will provide autocomplete and validation for your catalogs.yml file.

3. Apply catalogs to .yarnrc.yml

$ yarn catalogs apply

This command reads catalogs.yml, resolves all inheritance, and writes the flattened catalogs to .yarnrc.yml.

Example output:

$ yarn catalogs apply
➤ YN0000: stable:
➤ YN0000:   + react: npm:18.2.0
➤ YN0000:   - react: npm:18.0.0

➤ YN0000: ✓ Applied 1 named catalog group to .yarnrc.yml
➤ YN0000: Done in 0s 2ms

If there are no changes, you'll see:

$ yarn catalogs apply
➤ YN0000: No changes to apply - .yarnrc.yml is already up to date
➤ YN0000: Done in 0s 1ms

The generated .yarnrc.yml will look like:

# .yarnrc.yml (generated - do not edit catalogs here)

catalog:
  lodash: npm:4.17.21

catalogs:
  stable:
    react: npm:18.0.0
    typescript: npm:5.1.0

  stable/canary:
    react: npm:18.2.0
    typescript: npm:5.1.0  # Inherited and resolved

  beta:
    react: npm:19.0.0

4. Use catalog protocol in package.json

{
  "dependencies": {
    "lodash": "catalog:",                 // Uses root catalog
    "react": "catalog:stable",            // Uses stable catalog
    "typescript": "catalog:stable/canary" // Uses stable/canary catalog
  }
}

Yarn's native catalog resolution will automatically resolve these to the versions defined in .yarnrc.yml.

Advanced Features

Check Mode

Check if .yarnrc.yml is up to date with catalogs.yml:

$ yarn catalogs apply --check

This is useful in CI/CD pipelines to ensure catalogs are properly synchronized. The command will:

  • Exit with code 0 if .yarnrc.yml is up to date
  • Exit with code 1 and show a diff of changes if .yarnrc.yml is out of date

Example output when changes are needed:

$ yarn catalogs apply --check
➤ YN0000: .yarnrc.yml is out of date. Run 'yarn catalogs apply' to update it.

➤ YN0000: stable:
➤ YN0000:   + react: npm:18.2.0
➤ YN0000:   - react: npm:18.0.0

➤ YN0000: Would apply 1 named catalog group to .yarnrc.yml
➤ YN0000: Failed with errors in 0s 1ms

Example output when up to date:

$ yarn catalogs apply --check
➤ YN0000: ✓ .yarnrc.yml is up to date
➤ YN0000: Done in 0s 1ms

Protocol Support

You can use any protocol supported by Yarn:

# In catalogs.yml
list:
  stable:
    react: npm:18.0.0
    next: npm:13.4.9
    lodash: patch:lodash@4.17.21#./.patches/lodash.patch

Scoped Packages

Scoped packages work as expected:

# In catalogs.yml
list:
  stable:
    "@emotion/react": npm:11.11.1
    "@types/react": npm:18.2.15
    "@tanstack/react-query": npm:5.0.0

Catalog Group Inheritance

Catalog groups can inherit from parent groups using the / delimiter:

# In catalogs.yml
list:
  stable:
    react: npm:18.0.0
    lodash: npm:4.17.21
    typescript: npm:5.1.6

  stable/canary:
    react: npm:18.2.0       # Overrides parent version
    # lodash: npm:4.17.21   (inherited from stable)
    # typescript: npm:5.1.6 (inherited from stable)

  stable/canary/next:
    react: npm:18.3.1  # Overrides parent version
    # All other packages inherited from stable/canary

After running yarn catalogs apply, all inheritance is resolved and written to .yarnrc.yml.

Default Catalogs

The default option in catalogs.yml automatically applies a catalog when running yarn add:

# In catalogs.yml
options:
  default: [stable, root]

list:
  root:
    lodash: npm:4.17.21
  stable:
    react: npm:18.0.0
    typescript: npm:5.1.0
yarn add react       # Automatically uses catalog:stable
yarn add lodash      # Falls back to catalog: (root)
yarn add unknown-pkg # Normal installation (not in any catalog)

"max" Mode

Set default: max to automatically use the most frequently used catalog in the current workspace:

# In catalogs.yml
options:
  default: max

list:
  stable:
    react: npm:18.0.0
    next: npm:14.0.0
  beta:
    react: npm:19.0.0
    next: npm:15.0.0

If your package.json has more catalog:stable dependencies than catalog:beta, running yarn add next will automatically use catalog:stable.

Validation

The plugin provides a workspace-based validation system for running pre-checks on your dependencies. The validation field is a top-level array where each entry specifies workspace patterns and the rules to apply:

# In catalogs.yml
validation:
  - workspaces: ["*"]  # Match all workspaces
    rules:
      catalog_protocol_usage: warn

list:
  stable:
    react: npm:18.0.0

Available Rules

catalog_protocol_usage

Controls whether dependencies should use the catalog: protocol:

  • strict: MUST use catalog protocol. Throws errors if a dependency exists in the catalog but doesn't use catalog:.
  • warn: SHOULD use catalog protocol. Shows warnings if a dependency exists in the catalog but doesn't use catalog:.
  • optional: CAN use catalog protocol. No errors or warnings.
  • restrict: MUST NOT use catalog protocol. Throws errors if catalog: protocol is used.

Workspace-Based Validation

You can apply different validation rules to different workspaces using glob patterns. The first matching rule wins:

# In catalogs.yml
validation:
  - workspaces: ["@myorg/server-*"]  # Server packages must use catalogs
    rules:
      catalog_protocol_usage: strict

  - workspaces: ["@myorg/experimental-*"]  # Experimental packages can't use catalogs
    rules:
      catalog_protocol_usage: restrict

  - workspaces: ["*"]  # All other packages get warnings
    rules:
      catalog_protocol_usage: warn

list:
  stable:
    react: npm:18.0.0
    typescript: npm:5.1.0

In this example:

  • Workspaces matching @myorg/server-* must use catalog: for dependencies listed in catalogs
  • Workspaces matching @myorg/experimental-* cannot use catalog: protocol at all
  • All other workspaces will see warnings if they don't use catalog: for listed dependencies

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT

About

A Yarn plugin that enables "Catalogs" - a workspace feature for defining dependency version ranges as reusable constants across your project.

Resources

License

Stars

Watchers

Forks

Contributors