A Yarn plugin that enables "Catalogs" - a workspace feature for defining dependency version ranges as reusable constants across your project.
Highly inspired by pnpm Catalogs.
In larger projects, especially monorepos, it's common to have the same dependencies used across multiple packages. Catalogs help you:
- Maintain consistent versions across your workspace
- Simplify upgrades by editing versions in just one place
- Reduce merge conflicts in package.json files
- Standardize dependencies across teams and repositories
yarn plugin import https://raw.githubusercontent.com/toss/yarn-plugin-catalogs/main/bundles/%40yarnpkg/plugin-catalogs.js
# in .yarnrc.yml
catalogs:
list:
# Root catalogs (can be referenced with just "catalog:")
react: 18.0.0
react-dom: 18.0.0
typescript: 5.1.6
# Named catalogs (must be referenced with "catalog:name")
beta:
react: 19.0.0
react-dom: 19.0.0
legacy:
react: 17.0.2
react-dom: 17.0.2
{
"dependencies": {
"react": "catalog:", // Uses version from root catalog
"react-dom": "catalog:", // Uses version from root catalog
"typescript": "catalog:", // Uses version from root catalog
"next": "catalog:beta", // Uses version from beta catalog
"styled-components": "catalog:legacy" // Uses version from legacy catalog
}
}
The plugin automatically adds the npm:
protocol if none is specified in the catalog:
# In .yarnrc.yml
catalogs:
list:
react: 18.0.0 // Will be transformed to "npm:18.0.0"
next: "npm:13.4.9" // Protocol explicitly specified
lodash: "patch:[email protected]#./.patches/lodash.patch" // Custom protocol
Scoped packages work as expected:
# In .yarnrc.yml
catalogs:
list:
"@emotion/react": 11.11.1
"@types/react": 18.2.15
beta:
"@tanstack/react-query": 5.0.0
{
"dependencies": {
"@emotion/react": "catalog:",
"@types/react": "catalog:",
"@tanstack/react-query": "catalog:beta"
}
}
The default
option automatically selects a catalog for yarn add
when no catalog name is specified. If multiple catalogs are listed, priority is determined by their order.
# In .yarnrc.yml
catalogs:
options:
default: [beta, legacy]
list:
beta:
react: 19.0.0
legacy:
react: 17.0.2
typescript: 4.8.3
yarn add react # Same as `yarn add react@catalog:beta`
yarn add typescript # Same as `yarn add typescript@catalog:legacy`
To use the root catalogs as the default, just set the default
option to root
:
# In .yarnrc.yml
catalogs:
options:
default: [root]
list:
react: 19.0.0
react-dom: 19.0.0
yarn add react # Same as `yarn add react@catalog:`
The default
option can also be set to a non-list value that defines a selection rule instead of specifying a catalog name. For example, max
selects the most frequently used catalog in package.json as the default.
# In .yarnrc.yml
catalogs:
options:
default: max
list:
beta:
react: 19.0.0
react-dom: 19.0.0
typescript: 5.1.6
next: 15.3.0
legacy:
react: 17.0.2
react-dom: 17.0.2
typescript: 4.8.3
next: 13.4.9
{
"dependencies": {
"react": "catalog:beta",
"react-dom": "catalog:beta",
"typescript": "catalog:legacy",
}
}
yarn add next # Same as `yarn add next@catalog:beta`
# because beta is the most frequently used catalog in package.json
Currently, only the max
option is available, but additional options may be added in the future.
You can disable catalogs for certain workspaces by listing their names in the ignoredWorkspaces
option. You can also use glob patterns here.
# In .yarnrc.yml
catalogs:
options:
ignoredWorkspaces: [package, test-*]
list:
react: 19.0.0
react-dom: 19.0.0
The ignored workspaces cannot use the catalog protocol, and the default alias group is also disabled for them.
Contributions are welcome! Please feel free to submit a Pull Request.
MIT