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.
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.ymlfile for better organization - Supporting hierarchical catalog inheritance (e.g.,
stable/canaryinherits fromstable) - Providing validation to ensure consistent catalog usage across workspaces
- Auto-applying default catalogs when adding dependencies
- Yarn 4.10.0 or later (for native catalog support)
yarn plugin import https://raw.githubusercontent.com/toss/yarn-plugin-catalogs/main/bundles/%40yarnpkg/plugin-catalogs.js# 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.0For 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.
$ yarn catalogs applyThis 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 2msIf 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 1msThe 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{
"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.
Check if .yarnrc.yml is up to date with catalogs.yml:
$ yarn catalogs apply --checkThis is useful in CI/CD pipelines to ensure catalogs are properly synchronized. The command will:
- Exit with code 0 if
.yarnrc.ymlis up to date - Exit with code 1 and show a diff of changes if
.yarnrc.ymlis 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 1msExample output when up to date:
$ yarn catalogs apply --check
➤ YN0000: ✓ .yarnrc.yml is up to date
➤ YN0000: Done in 0s 1msYou 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.patchScoped 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.0Catalog 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/canaryAfter running yarn catalogs apply, all inheritance is resolved and written to .yarnrc.yml.
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.0yarn add react # Automatically uses catalog:stable
yarn add lodash # Falls back to catalog: (root)
yarn add unknown-pkg # Normal installation (not in any catalog)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.0If your package.json has more catalog:stable dependencies than catalog:beta, running yarn add next will automatically use catalog:stable.
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.0Controls whether dependencies should use the catalog: protocol:
strict: MUST use catalog protocol. Throws errors if a dependency exists in the catalog but doesn't usecatalog:.warn: SHOULD use catalog protocol. Shows warnings if a dependency exists in the catalog but doesn't usecatalog:.optional: CAN use catalog protocol. No errors or warnings.restrict: MUST NOT use catalog protocol. Throws errors ifcatalog:protocol is used.
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.0In this example:
- Workspaces matching
@myorg/server-*must usecatalog:for dependencies listed in catalogs - Workspaces matching
@myorg/experimental-*cannot usecatalog:protocol at all - All other workspaces will see warnings if they don't use
catalog:for listed dependencies
Contributions are welcome! Please feel free to submit a Pull Request.
MIT