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
- Filtering workspaces with opt-in (
includedWorkspaces) and opt-out (ignoredWorkspaces) options
- 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: warn # Optional: 'warn' | 'strict' | 'off'
includedWorkspaces: [] # Optional: Workspaces to include
ignoredWorkspaces: [] # Optional: Workspaces to ignore
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:[email protected]#./.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.
Control which workspaces are included in catalog protocol processing using includedWorkspaces and ignoredWorkspaces options.
Use includedWorkspaces to specify which workspaces should be processed for catalogs. Only matching workspaces will receive catalog validation and default catalog auto-application:
# In catalogs.yml
options:
includedWorkspaces: [apps-*, packages]
list:
stable:
react: npm:18.0.0When includedWorkspaces is specified:
- Only matching workspaces receive validation warnings/errors
- Only matching workspaces have default catalogs auto-applied
If includedWorkspaces is not specified, all workspaces are included by default.
Use ignoredWorkspaces to exclude specific workspaces from catalog processing:
# In catalogs.yml
options:
ignoredWorkspaces: [test-*, scripts]
list:
stable:
react: npm:18.0.0Ignored workspaces:
- Won't receive validation warnings/errors
- Won't have default catalogs auto-applied
ignoredWorkspaces takes precedence over includedWorkspaces.
Control how strictly catalog usage is enforced:
# In catalogs.yml
options:
validation: warn # 'warn' | 'strict' | 'off'
list:
stable:
react: npm:18.0.0warn(default): Show warnings for dependencies that should use catalogsstrict: Throw errors and prevent installationoff: Disable validation entirely
Set different validation levels for each catalog:
# In catalogs.yml
options:
validation:
stable: strict # Strictly enforce stable catalog
beta: warn # Warn for beta catalog
experimental: off # No validation for experimental
list:
stable:
react: npm:18.0.0
beta:
react: npm:19.0.0-rc
experimental:
react: npm:19.0.0-alphaValidation Rules:
- When a package exists in multiple catalogs, the strictest level applies (
strict>warn>off) - Hierarchical catalogs inherit validation settings from their parent groups:
# In catalogs.yml
options:
validation:
stable: off # Parent group has validation off
stable/canary: strict # Child group enforces strictly
list:
stable:
react: npm:18.0.0
stable/canary:
react: npm:18.2.0
lodash: npm:4.17.21In this example:
reactwill usestrictvalidation (fromstable/canary)lodashwill usestrictvalidation (fromstable/canarysince it's not in parent)
Contributions are welcome! Please feel free to submit a Pull Request.
MIT