Technical Documentation: JamieMason/syncpack
ℹ️ Provenance: Multi-Tier Ingestion · CodeWiki Reference
Overview (`README.md`)
syncpack
Syncpack is used by AWS, Cloudflare, DataDog, Electron, GoDaddy, Lottie, Microsoft, PostHog, Qwik, Raycast, Salesforce, TopTal, Vercel, VoltAgent, WooCommerce and others.
Some of the things it can do are:
- Find and fix dependency version mismatches.
- Enforce a single version policy, or create partitions with separate policies.
- Find and bump outdated versions from the npm registry.
- Ensure some dependencies always remain pinned at a specific version.
- Ban some dependencies from being used: anywhere, or in specific places.
- Define rules for where exact or loose semver ranges should be used, including in catalogs.
- Assign packages as the source of truth for specific dependencies' versions.
- Sort and format package.json files consistently.
- Auto-migrate all or parts of your repo to pnpm catalogs or bun catalogs.
- Bump outdated versions in catalogs.
Installation
npm install --save-dev syncpackGuides
Commands
All command line options can be combined to target packages and dependencies in multiple ways.
[lint](https://syncpack.dev/command/lint)
Ensure that multiple packages requiring the same dependency define the same version, so that every package requires eg. [email protected], instead of a combination of [email protected], [email protected], and [email protected].
Examples
# Find all issues in "dependencies" or "devDependencies"
syncpack lint --dependency-types prod,dev
# Only lint issues in "react" specifically
syncpack lint --dependencies react
# Look for issues in dependencies containing "react" in the name
syncpack lint --dependencies '**react**'
# Find issues in scoped packages only
syncpack lint --dependencies '@types/**'
# Find issues everywhere except "peerDependencies"
syncpack lint --dependency-types '!peer'
# Only look for issues where an exact version is used (eg "1.2.3")
syncpack lint --specifier-types exact
# Sort dependencies by how many times they are used
syncpack lint --sort count
# See more examples
syncpack lint --help
# See a short summary of options
syncpack lint -h[fix](https://syncpack.dev/command/fix)
Fix every autofixable issue found by syncpack lint.
Examples
# Only fix issues in dependencies and devDependencies
syncpack fix --dependency-types prod,dev
# Only fix inconsistencies with exact versions (eg "1.2.3")
syncpack fix --specifier-types exact
# Only fix issues in "react" specifically
syncpack fix --dependencies react
# See more examples
syncpack fix --help
# See a short summary of options
syncpack fix -h[update](https://syncpack.dev/command/update)
Update packages to the latest versions from the npm registry, wherever they are in your monorepo, including pnpm catalog entries in pnpm-workspace.yaml.Semver range preferences are preserved when updating.
Examples
# Accept any update in latest (x.x.x)
syncpack update --target latest
# Only update minor versions (1.x.x)
syncpack update --target minor
# Only update patch versions (1.2.x)
syncpack update --target patch
# Pick which updates to apply through an interactive prompt
syncpack update --interactive
# Interactively pick from patch updates only
syncpack update --interactive --target patch
# Interactively pick which @aws-sdk packages to update
syncpack update --interactive --dependencies '@aws-sdk/**'
# Check for outdated dependencies in one package
syncpack update --check --source 'packages/pingu/package.json'
# Update dependencies and devDependencies in the whole monorepo
syncpack update --dependency-types dev,prod
# Update only pnpm catalog entries in pnpm-workspace.yaml
syncpack update --dependency-types pnpmCatalog
# Update only the named pnpm catalog 'react18'
syncpack update --dependency-types 'pnpmCatalog:react18'
# Only update dependencies with a semver range specifier (^, ~, etc.)
syncpack update --specifier-types range
# Update dependencies where name exactly matches 'react'
syncpack update --dependencies 'react'
# Update dependencies where name contains 'react'
syncpack update --dependencies '**react**'
# Update dependencies with the '@aws-sdk' scope
syncpack update --dependencies '@aws-sdk/**'
# See more examples
syncpack update --help
# See a short summary of options
syncpack update -h[format](https://syncpack.dev/command/format)
Organise package.json files according to a conventional format, where fields appear in a predictable order and nested fields are ordered alphabetically. Shorthand properties are used where available, such as the "repository" and "bugs" fields.
Examples
# Fix every formatting issue in the monorepo
syncpack format
# List all formatting issues in the monorepo
syncpack format --check
# Check the formatting of one package
syncpack format --check --source 'packages/pingu/package.json'
# See more examples
syncpack format --help
# See a short summary of options
syncpack format -h[list](https://syncpack.dev/command/list)
Query and inspect all dependencies in your project, both valid and invalid.
Examples
# Sort dependencies by how many times they are used
syncpack list --sort count
# Show every instance of each dependency, not just their names
syncpack list --show instances
# Show dependencies ignored in your syncpack config
syncpack list --show ignored
# Show highest level of detail
syncpack list --show all
# Choose only some values
syncpack list --show hints,statuses
# List all "peerDependencies"
syncpack list --dependency-types peer
# List all types packages
syncpack list --dependencies '@types/**'
# List instances of an exact version being used as a peer dependency
syncpack list --specifier-types exact --show instances --dependency-types peer
# See more examples
syncpack list --help
# See a short summary of options
syncpack list -h[json](https://syncpack.dev/command/json)
Output the state of every instance of every dependency as a JSON object, one per line. This command is best used with tools like jq for filtering and processing.
Examples
# Output all dependencies as JSON
syncpack json
# Output only AWS SDK dependencies
syncpack json --dependencies '@aws-sdk/**'
# Count dependencies by type
syncpack json | jq -r '.dependencyType' | sort | uniq -c
# See more examples
syncpack json --help
# See a short summary of options
syncpack json -hBadges
Site Src Content Docs Guide Getting Started (`site/src/content/docs/guide/getting-started.mdx`)
title: Syncpack slug: index sidebar: label: Getting Started
Syncpack is a command-line tool for consistent dependency versions in large JavaScript Monorepos, it is used by AWS, Cloudflare, DataDog, Electron, GoDaddy, Lottie, Microsoft, PostHog, Qwik, Raycast, Salesforce, TopTal, Vercel, VoltAgent, WooCommerce and others.
Some of the things it can do are:
- Find and fix dependency version mismatches.
- Enforce a single version policy, or create partitions with separate policies.
- Find and bump outdated versions from the npm registry.
- Ensure some dependencies always remain pinned at a specific version.
- Ban some dependencies from being used: anywhere, or in specific places.
- Define rules for where exact or loose semver ranges should be used, including in catalogs.
- Assign packages as the source of truth for specific dependencies' versions.
- Sort and format package.json files consistently.
- Auto-migrate all or parts of your repo to pnpm catalogs or bun catalogs.
- Bump outdated versions in catalogs.
Try it
The fastest way to try syncpack is via npx.
npx syncpack list --dependency-types prodRun this command from the root directory of a monorepo and it will list every dependency installed under a dependencies property of a package.json file in the project.
Syncpack uses your package manager's workspace configuration to locate your package.json files, or you can target specific files using the source configuration or --source option.
For any given command, browse a summary of its options with -h
npx syncpack update -hor display documentation and examples with --help
npx syncpack update --helpInstall
When setting up a project for real, install syncpack in devDependencies so that everyone working on your project uses the same version.
npm install syncpack --save-devThe locally installed binary can be run using npm exec
npm exec syncpack -- listIntroduction
:::note
The examples below assume syncpack is installed globally. Replace syncpack with npx syncpack if you haven't installed it or npm exec syncpack if you have installed it locally.
:::
Let's see which dependencies we use the most.
syncpack list --dependency-types prod --sort countSome of our dependencies might have status codes next to them, if our Terminal supports it we can command + click each error to view its documentation, or each filename to open the file.
To focus only on dependencies with errors, use lint instead of list.
syncpack lint --dependency-types prodIf the suggested changes look ok, we can autofix them.
syncpack fix --dependency-types prod:::tip
After running fix or update, run your package manager (npm install, pnpm install, etc.) to update your lockfile.
:::
Or we could choose to only autofix one of them, for this example I've chosen react.
syncpack fix --dependency-types prod --dependencies reactAll of syncpack's commands can be filtered in the same way, let's see if react needs updating.
syncpack update --check --dependencies reactOr list every dependency with eslint somewhere in the name.
syncpack list --dependencies '**eslint**'Or every dependency published under the @types scope.
syncpack list --dependencies '@types/**'We can find every dependency installed with an exact version number.
syncpack list --specifier-types exactOr look for updates to devDependencies where only the patch version is newer than what we have installed.
syncpack update --check --dependency-types dev --target patchAnd by removing the --check option we can write the newer versions to our files.
syncpack update --dependencies reactEach command supports --help for examples and available options.
syncpack list --helpConfiguration
Create a .syncpackrc file in the root of your repo to customise behaviour. One way to get started is to focus on production dependencies, then gradually broaden out as you feel comfortable. This is done using Version Groups.
{
"versionGroups": [
{
"label": "Sync all production dependencies",
"dependencyTypes": ["prod"]
},
{
"label": "Ignore everything else",
"isIgnored": true
}
]
}Or you could focus on specific dependencies and fix those first:
{
"versionGroups": [
{
"label": "Sync react dependencies only",
"dependencies": ["react", "react-dom"],
"dependencyTypes": ["prod"]
},
{
"label": "Ignore everything else",
"isIgnored": true
}
]
}`workspace:*` dependencies
This is a popular configuration which ensures that workspace:* is always used when you depend on a package which is developed in your monorepo.
{
"versionGroups": [
{
"label": "Use `workspace:*` protocol for local packages",
// for packages developed in your monorepo
"dependencies": ["$LOCAL"],
// when they are installed as prod or dev dependencies
"dependencyTypes": ["dev", "prod"],
// always use the workspace protocol to reference them
"pinVersion": "workspace:*"
},
{
"label": "Ignore everything else",
"isIgnored": true
}
]
}Further reading
- Read the
Peer Dependenciesguide if your projects uses them, it will be important to understand them from a version consistency point of view. Semver Groupsconfiguration lets you ensure for example that version numbers indevDependenciesalways use^whiledependenciesalways use~.- With
Version Groupsconfiguration you can slice up your packages and dependencies in a lot of different ways. Each group can have different versioning policies to the rest of the repo, but are each kept internally consistent and valid according to their own rules.
Fixtures Fluid Framework Docs Package.Json (`fixtures/fluid-framework/docs/package.json`)
{
"name": "fluid-framework-docs-site",
"version": "0.0.0",
"private": true,
"homepage": "https://fluidframework.com",
"repository": {
"type": "git",
"url": "https://github.com/microsoft/FluidFramework.git",
"directory": "docs"
},
"license": "MIT",
"author": "Microsoft and contributors",
"scripts": {
"build": "concurrently npm:build:site npm:build:test",
"build:api-documentation": "npm run download-doc-models && npm run generate-api-documentation",
"prebuild:docusaurus": "npm run generate-versions",
"build:docusaurus": "docusaurus build",
"build:generate-content": "concurrently npm:build:markdown-magic npm:build:api-documentation",
"build:markdown-magic": "markdown-magic",
"build:site": "npm run build:generate-content && npm run build:docusaurus",
"build:test": "tsc --project test/tsconfig.json --pretty --noEmit",
"check-links": "linkcheck http://localhost:3000 --skip-file skipped-urls.txt",
"ci:check-links": "start-server-and-test "npm run serve -- --no-open" 3000 check-links",
"clean": "concurrently "npm:clean:*"",
"clean:api-documentation": "node ./infra/clean-api-documentation.mjs",
"clean:doc-models": "rimraf --glob .doc-models",
"clean:docusaurus": "docusaurus clear",
"clean:test": "rimraf --glob test-results",
"clean:versions-json": "rimraf --glob ./versions.json",
"download-doc-models": "node ./infra/download-doc-models.mjs",
"eslint": "eslint . --format stylish",
"eslint:fix": "eslint . --format stylish --fix",
"format": "npm run prettier:fix",
"generate-api-documentation": "dotenv -- node ./infra/generate-api-documentation.mjs",
"generate-versions": "dotenv -- node ./infra/generate-versions.mjs",
"preinstall": "node ../scripts/only-pnpm.cjs",
"lint": "concurrently npm:eslint npm:prettier",
"lint:fix": "npm run eslint:fix && npm run prettier:fix",
"prettier": "prettier --check . --cache --ignore-path ../.prettierignore",
"prettier:fix": "prettier --write . --cache --ignore-path ../.prettierignore",
"rebuild": "npm run clean && npm run build",
"serve": "docusaurus serve",
"serve-with-azure-emulation": "swa start --config-name ff-doc-site",
"prestart": "npm run generate-versions",
"start": "docusaurus start",
"pretest": "playwright install --with-deps",
"test": "playwright test"
},
"browserslist": {
"production": [
">0.5%",
"not dead",
"not op_mini all"
],
"development": [
"last 3 chrome version",
"last 3 firefox version",
"last 5 safari version"
]
},
"devDependencies": {
"@azure/static-web-apps-cli": "^2.0.1",
"@docusaurus/core": "^3.6.2",
"@docusaurus/eslint-plugin": "^3.6.2",
"@docusaurus/module-type-aliases": "^3.6.2",
"@docusaurus/plugin-content-docs": "^3.6.2",
"@docusaurus/preset-classic": "^3.6.2",
"@docusaurus/theme-common": "^3.6.2",
"@docusaurus/theme-mermaid": "^3.6.2",
"@docusaurus/tsconfig": "^3.6.2",
"@docusaurus/types": "^3.6.2",
"@fluid-tools/api-markdown-documenter": "^0.23.2",
"@fluid-tools/markdown-magic": "file:../tools/markdown-magic",
"@fluidframework/build-common": "^2.0.3",
"@fluidframework/eslint-config-fluid": "^6.1.0",
"@microsoft/applicationinsights-react-js": "^17.3.4",
"@microsoft/applicationinsights-web": "^3.3.4",
"@playwright/test": "^1.49.0",
"@rushstack/node-core-library": "^5.9.0",
"@types/fs-extra": "^11.0.4",
"@types/hast": "^3.0.4",
"@types/mdast": "^4.0.4",
"@types/node": "^22.9.1",
"chalk": "^5.3.0",
"clsx": "^2.1.1",
"concurrently": "^9.2.1",
"cross-env": "^7.0.3",
"dill-cli": "^0.1.3",
"docusaurus-plugin-sass": "^0.2.5",
"docusaurus-theme-search-typesense": "0.23.1-0",
"dompurify": "^3.2.6",
"dotenv": "^16.4.7",
"dotenv-cli": "^7.4.3",
"eslint": "~8.57.0",
"eslint-config-prettier": "~10.1.8",
"eslint-mdx": "^3.1.5",
"eslint-plugin-mdx": "^3.1.5",
"fs-extra": "^11.2.0",
"linkcheck-bin": "3.0.0-2",
"lunr": "^2.3.9",
"mdast-util-directive": "^3.1.0",
"playwright": "^1.49.0",
"prettier": "^3.3.3",
"prism-react-renderer": "^2.4.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"rimraf": "^6.1.3",
"simple-git": "^3.27.0",
"start-server-and-test": "^2.0.8",
"typescript": "~5.5.4",
"uuid": "^11.0.3"
},
"packageManager": "[email protected]+sha512.bbd16e6d7286fd7e01f6b3c0b3c932cda2965c06a908328f74663f10a9aea51f1129eea615134bf992831b009eabe167ecb7008b597f40ff9bc75946aadfb08d",
"engines": {
"node": ">=18.0"
},
"pnpm": {
"onlyBuiltDependencies": [
"@parcel/watcher",
"core-js",
"core-js-pure",
"keytar",
"linkcheck-bin",
"typesense-instantsearch-adapter",
"unrs-resolver"
]
}
}
Fixtures Fluid Framework Docs Pnpm Workspace.Yaml (`fixtures/fluid-framework/docs/pnpm-workspace.yaml`)
This file is a workaround. pnpm does not support nesting packages under a workspace that is not managed by the
workspace. That is, if there's a pnpm-workspace.yaml file anywhere in the parent hierarchy, pnpm doesn't install the
package individually like one might expect.
Because we have the client release group at the root of the repo, there's a pnpm-workspace.yaml file in the hierarchy
for our independent packages as well. This file makes pnpm treat the project as a one-package workspace.
packages:
- .
These entries must be duplicated from package.json due to a pnpm bug where onlyBuiltDependencies
in package.json is not respected when the workspace has its own lockfile.
See: https://github.com/pnpm/pnpm/issues/9082
onlyBuiltDependencies:
- '@parcel/watcher'
- core-js
- core-js-pure
- keytar
- linkcheck-bin
- typesense-instantsearch-adapter
- unrs-resolver
Supply chain security settings - see /DEV.md for documentation
minimumReleaseAge: 1440
resolutionMode: highest
blockExoticSubdeps: true
trustPolicy: no-downgrade
strictDepBuilds: true
Fixtures Fluid Framework Docs Api Package.Json (`fixtures/fluid-framework/docs/api/package.json`)
{
"name": "fluidframework-docs-api",
"homepage": "https://fluidframework.com",
"repository": {
"type": "git",
"url": "https://github.com/microsoft/FluidFramework.git",
"directory": "docs/api"
},
"license": "MIT",
"author": "Microsoft and contributors",
"type": "commonjs"
}
Site Src Content Docs Command (`site/src/content/docs/command.mdx`)
title: Commands
import { CardGrid, LinkCard } from "@astrojs/starlight/components";
import { getCollection } from "astro:content";
export const allDocs = await getCollection("docs");
export const pages = allDocs
.filter((doc) => doc.id.startsWith("command/") && doc.id !== "command")
.sort((a, b) => a.data.title.localeCompare(b.data.title));
Syncpack provides several commands to lint, fix, format, and update dependencies in your monorepo.
Site Src Content Docs Config (`site/src/content/docs/config.mdx`)
title: Configuration File
import { CardGrid, LinkCard } from "@astrojs/starlight/components";
import { getCollection } from "astro:content";
export const allDocs = await getCollection("docs");
export const pages = allDocs
.filter((doc) => doc.id.startsWith("config/") && doc.id !== "config")
.sort((a, b) => a.data.title.localeCompare(b.data.title));
Configure syncpack's behavior using a .syncpackrc file in your project root. These options control formatting, sorting, dependency management, and version constraints.
Site Src Content Docs Guide (`site/src/content/docs/guide.mdx`)
title: Guides
import { CardGrid, LinkCard } from "@astrojs/starlight/components";
import { getCollection } from "astro:content";
export const allDocs = await getCollection("docs");
export const pages = allDocs
.filter((doc) => doc.id.startsWith("guide/") && doc.id !== "guide")
.sort((a, b) => a.data.title.localeCompare(b.data.title));
Step-by-step guides to help you get the most out of Syncpack in your JavaScript monorepo.
Site Src Content Docs Reference (`site/src/content/docs/reference.mdx`)
title: Reference
import { CardGrid, LinkCard } from "@astrojs/starlight/components";
import { getCollection } from "astro:content";
export const allDocs = await getCollection("docs");
export const pages = allDocs
.filter((doc) => doc.id.startsWith("reference/") && doc.id !== "reference")
.sort((a, b) => a.data.title.localeCompare(b.data.title));
Reference documentation covering dependency types, specifier types, status codes, and glossary of terms used throughout Syncpack.
Site Src Content Docs Semver Groups (`site/src/content/docs/semver-groups.mdx`)
title: Semver Groups
import { CardGrid, LinkCard } from "@astrojs/starlight/components";
import { getCollection } from "astro:content";
export const allDocs = await getCollection("docs");
export const pages = allDocs
.filter(
(doc) => doc.id.startsWith("semver-groups/") && doc.id !== "semver-groups",
)
.sort((a, b) => a.data.title.localeCompare(b.data.title));
Allow some packages to have different semver range rules to the rest of your monorepo. Each dependency can only belong to one semver group, the first rule which matches a given dependency and package will apply.
Examples
1: Every dependency of @myrepo/library should have a semver range of ~, regardless of what the rest of the monorepo uses:
{
"semverGroups": [
{
"packages": ["@myrepo/library"],
"range": "~"
}
]
}2: Every dependency of @myrepo/library whose name matches @foo/** should have a semver range of ^, regardless of what the rest of that package or the rest of the monorepo uses:
{
"semverGroups": [
{
"dependencies": ["@foo/**"],
"packages": ["@myrepo/library"],
"range": "^"
}
]
}3: Every dependency in the monorepo whose name matches @foo/** should have a semver range of ~, regardless of what the rest of the monorepo uses:
{
"semverGroups": [
{
"dependencies": ["@foo/**"],
"range": "~"
}
]
}4: Production dependencies should have fixed version numbers, but development and peer dependencies can be broader.
{
"semverGroups": [
{
"dependencyTypes": [
"prod",
"resolutions",
"overrides",
"pnpmOverrides",
"local"
],
"range": ""
},
{
"dependencyTypes": ["dev"],
"range": "~"
},
{
"dependencyTypes": ["peer"],
"range": "^"
}
]
}Variants
Site Src Content Docs Update Groups (`site/src/content/docs/update-groups.mdx`)
title: Update Groups
import { CardGrid, LinkCard } from "@astrojs/starlight/components";
import { Tabs, TabItem } from "@astrojs/starlight/components";
import { getCollection } from "astro:content";
export const allDocs = await getCollection("docs");
export const pages = allDocs
.filter(
(doc) => doc.id.startsWith("update-groups/") && doc.id !== "update-groups",
)
.sort((a, b) => a.data.title.localeCompare(b.data.title));
Update groups give you per-dependency control over what counts as an eligible registry update for the update command. Use them to clamp some dependencies to patch-only updates, others to minor, and to opt specific dependencies out of update consideration entirely.
How groups are assigned
When syncpack reads each instance of a dependency, it walks through your updateGroups array in source code order until it finds a match. The first match wins and syncpack stops searching.
An instance can match at most one update group. Instances which do not match any group fall through to the CLI's --target value (which defaults to latest).
When --target is set
When both the CLI's --target flag and a matched group's target apply to the same instance, the stricter of the two wins.
CLI --target |
Group target |
Effective |
|---|---|---|
latest |
patch |
patch |
latest |
minor |
minor |
minor |
patch |
patch |
patch |
latest |
patch |
This means you can safely set the CLI default to latest and use update groups to opt individual dependencies into stricter rules, without the CLI ever loosening a group's policy.
Examples
{
"updateGroups": [
// Storybook bumps tend to be coordinated; only ever take patch updates.
{ "dependencies": ["storybook", "@storybook/**"], "target": "patch" },
// Dev tooling can move freely on minor.
{ "dependencyTypes": ["dev"], "target": "minor" },
// Production deps stay on patch only.
{ "dependencyTypes": ["prod"], "target": "patch" },
// Peer dependencies are owned by consumers; never update them.
{ "dependencyTypes": ["peer"], "isIgnored": true },
],
}Default values
Any properties of an update group that are omitted will match-all by default, so the two examples below are equivalent.
{
"updateGroups": [
{
"target": "patch"
}
]
}{
"updateGroups": [
{
"dependencies": ["**"],
"dependencyTypes": ["**"],
"packages": ["**"],
"specifierTypes": ["**"],
"target": "patch"
}
]
}Variants
Site Src Content Docs Version Groups (`site/src/content/docs/version-groups.mdx`)
title: Version Groups
import { CardGrid, LinkCard } from "@astrojs/starlight/components";
import { Tabs, TabItem } from "@astrojs/starlight/components";
import { getCollection } from "astro:content";
export const allDocs = await getCollection("docs");
export const pages = allDocs
.filter(
(doc) =>
doc.id.startsWith("version-groups/") && doc.id !== "version-groups",
)
.sort((a, b) => a.data.title.localeCompare(b.data.title));
Version groups split your project into isolated sections, each with their own policy for how versions should be managed.
Without any configuration, your entire monorepo is one big Highest Semver version group, but there are situations where you will want to break it up.
How groups are assigned
When syncpack reads each instance of a dependency, it walks through your versionGroups array in source code order until it finds a match. The first match wins and syncpack stops searching.
An instance can only belong to one Version Group, and the type of group it belongs to defines the rules that form its version policy.
If an instance doesn't match any of your version groups, or you don't have any, they are assigned to a default Highest Semver version group which applies to everything not already assigned to something more specific.
Order your groups by most specific first to most general last, otherwise the generic groups will always win and the specific groups will never be read.
{
"versionGroups": [
{
"label": "Please use lodash instead of underscore",
"dependencies": ["underscore"],
"isBanned": true
},
{
"label": "Ignore everything else",
"isIgnored": true
}
]
}Default values
Any properties of a version group that are omitted will match-all by default, so the two examples in the tabs below are equivalent.
{
"versionGroups": [
{
"label": "Ignore everything",
"isIgnored": true
}
]
}{
"versionGroups": [
{
"label": "Ignore everything",
"dependencies": ["**"],
"dependencyTypes": ["**"],
"packages": ["**"],
"specifierTypes": ["**"],
"isIgnored": true
}
]
}Variants
Site Src Content Docs Command Fix (`site/src/content/docs/command/fix.mdx`)
title: fix
import { Badge } from "@astrojs/starlight/components";
import ConfigOption from "@partials/option/config.mdx";
import DependenciesOption from "@partials/option/dependencies.mdx";
import DependencyTypesOption from "@partials/option/dependency-types.mdx";
import DryRunOption from "@partials/option/dry-run.mdx";
import HelpOption from "@partials/option/help.mdx";
import LogLevelsOption from "@partials/option/log-levels.mdx";
import NoAnsiOption from "@partials/option/no-ansi.mdx";
import ReporterOption from "@partials/option/reporter-fix.mdx";
import ShowOption from "@partials/option/show-versions.mdx";
import SortOption from "@partials/option/sort.mdx";
import SourceOption from "@partials/option/source.mdx";
import SourceModeOption from "@partials/option/source-mode.mdx";
import SpecifierTypesOption from "@partials/option/specifier-types.mdx";
import QuoteFilters from "@partials/tips/quote-filters.mdx";
Fix version mismatches in your monorepo. When the same dependency has different versions across packages, fix updates them to match your configuration rules. Use this to resolve issues reported by lint. Does not fix formatting. Use format for that.
Examples
# Preview changes without modifying files
syncpack fix --dry-run
# Fix only dependencies and devDependencies (exclude peer, optional)
syncpack fix --dependency-types prod,dev
# Fix inconsistencies with exact versions only (eg "1.2.3", not "^1.2.3")
syncpack fix --specifier-types exact
# Fix issues in "react" across all packages
syncpack fix --dependencies react
# Fix scoped packages like @types/* but exclude others
syncpack fix --dependencies '@types/**'
# See more examples
syncpack fix --help
# See a short summary of options
syncpack fix -hOptions
--config " /> ')" title="Copy section prompt for LLMs"> Copy Section
--dependencies " /> ')" title="Copy section prompt for LLMs"> Copy Section
--dependency-types " /> ')" title="Copy section prompt for LLMs"> Copy Section
--dry-run
--log-levels " /> ')" title="Copy section prompt for LLMs"> Copy Section
--no-ansi
--reporter " /> ')" title="Copy section prompt for LLMs"> Copy Section
--show " /> ')" title="Copy section prompt for LLMs"> Copy Section
--sort " /> ')" title="Copy section prompt for LLMs"> Copy Section
--source " /> ')" title="Copy section prompt for LLMs"> Copy Section
--source-mode " /> ')" title="Copy section prompt for LLMs"> Copy Section
--specifier-types " /> ')" title="Copy section prompt for LLMs"> Copy Section
--help
Site Src Content Docs Command Format (`site/src/content/docs/command/format.mdx`)
title: format
import { Badge } from "@astrojs/starlight/components";
import CheckOption from "@partials/option/check.mdx";
import ConfigOption from "@partials/option/config.mdx";
import DryRunOption from "@partials/option/dry-run.mdx";
import HelpOption from "@partials/option/help.mdx";
import LogLevelsOption from "@partials/option/log-levels.mdx";
import NoAnsiOption from "@partials/option/no-ansi.mdx";
import ReporterOption from "@partials/option/reporter-format.mdx";
import QuoteFilters from "@partials/tips/quote-filters.mdx";
import SourceOption from "@partials/option/source.mdx";
import SourceModeOption from "@partials/option/source-mode.mdx";
Format package.json files in your monorepo. Sorts fields into consistent order and alphabetises nested fields. Use this to maintain readable, diff-friendly package.json files. Does not change version numbers. Use fix for that.
Examples
# Fix every formatting issue in the monorepo
syncpack format
# List all formatting issues in the monorepo
syncpack format --check
# Check the formatting of one package
syncpack format --check --source 'packages/pingu/package.json'
# See more examples
syncpack format --help
# See a short summary of options
syncpack format -hOptions
--check
--config " /> ')" title="Copy section prompt for LLMs"> Copy Section
--dry-run
--log-levels " /> ')" title="Copy section prompt for LLMs"> Copy Section
--no-ansi
--reporter " /> ')" title="Copy section prompt for LLMs"> Copy Section
--source " /> ')" title="Copy section prompt for LLMs"> Copy Section
--source-mode " /> ')" title="Copy section prompt for LLMs"> Copy Section
--help
Site Src Content Docs Command Json (`site/src/content/docs/command/json.mdx`)
title: json
import { Badge } from "@astrojs/starlight/components";
import ConfigOption from "@partials/option/config.mdx";
import DependenciesOption from "@partials/option/dependencies.mdx";
import DependencyTypesOption from "@partials/option/dependency-types.mdx";
import HelpOption from "@partials/option/help.mdx";
import LogLevelsOption from "@partials/option/log-levels.mdx";
import NoAnsiOption from "@partials/option/no-ansi.mdx";
import SortOption from "@partials/option/sort.mdx";
import SourceOption from "@partials/option/source.mdx";
import SourceModeOption from "@partials/option/source-mode.mdx";
import SpecifierTypesOption from "@partials/option/specifier-types.mdx";
import QuoteFilters from "@partials/tips/quote-filters.mdx";
Export dependency data from your monorepo as JSON. Outputs one line per dependency instance with version, location, and status information. Use with tools like jq to analyse, filter, or pipe into other programs.
:::tip
The fix and format commands also support --reporter json for machine-readable output of their results. Use syncpack fix --reporter json for fixable version mismatches or syncpack format --reporter json for formatting issues.
:::
Examples
# Output all dependencies as JSON
syncpack json
# Output only AWS SDK dependencies
syncpack json --dependencies '@aws-sdk/**'
# Count dependencies by type
syncpack json | jq -r '.dependencyType' | sort | uniq -c
# See more examples
syncpack json --help
# See a short summary of options
syncpack json -hTypeScript
Each instance printed by syncpack json has the type JsonOutput
Options
--config " /> ')" title="Copy section prompt for LLMs"> Copy Section
--dependencies " /> ')" title="Copy section prompt for LLMs"> Copy Section
--dependency-types " /> ')" title="Copy section prompt for LLMs"> Copy Section
--log-levels " /> ')" title="Copy section prompt for LLMs"> Copy Section
--no-ansi
--sort " /> ')" title="Copy section prompt for LLMs"> Copy Section
--source " /> ')" title="Copy section prompt for LLMs"> Copy Section
--source-mode " /> ')" title="Copy section prompt for LLMs"> Copy Section
--specifier-types " /> ')" title="Copy section prompt for LLMs"> Copy Section
--help
Site Src Content Docs Command Lint (`site/src/content/docs/command/lint.mdx`)
title: lint
import { Badge } from "@astrojs/starlight/components";
import ConfigOption from "@partials/option/config.mdx";
import DependenciesOption from "@partials/option/dependencies.mdx";
import DependencyTypesOption from "@partials/option/dependency-types.mdx";
import HelpOption from "@partials/option/help.mdx";
import LogLevelsOption from "@partials/option/log-levels.mdx";
import NoAnsiOption from "@partials/option/no-ansi.mdx";
import QuoteFilters from "@partials/tips/quote-filters.mdx";
import ShowOption from "@partials/option/show-versions.mdx";
import SortOption from "@partials/option/sort.mdx";
import SourceOption from "@partials/option/source.mdx";
import SourceModeOption from "@partials/option/source-mode.mdx";
import SpecifierTypesOption from "@partials/option/specifier-types.mdx";
Check for version mismatches in your monorepo. Reports dependencies that don't match your configuration rules and exits with status code 1 if issues are found. Use fix to resolve reported issues. Does not check formatting. Use format --check for that.
Examples
# Find all issues in "dependencies" or "devDependencies"
syncpack lint --dependency-types prod,dev
# Only lint issues in "react" specifically
syncpack lint --dependencies react
# Look for issues in dependencies containing "react" in the name
syncpack lint --dependencies '**react**'
# Find issues in scoped packages only
syncpack lint --dependencies '@types/**'
# Find issues everywhere except "peerDependencies"
syncpack lint --dependency-types '!peer'
# Only look for issues where an exact version is used (eg "1.2.3")
syncpack lint --specifier-types exact
# Sort dependencies by how many times they are used
syncpack lint --sort count
# See more examples
syncpack lint --help
# See a short summary of options
syncpack lint -hOptions
--config " /> ')" title="Copy section prompt for LLMs"> Copy Section
--dependencies " /> ')" title="Copy section prompt for LLMs"> Copy Section
--dependency-types " /> ')" title="Copy section prompt for LLMs"> Copy Section
--log-levels " /> ')" title="Copy section prompt for LLMs"> Copy Section
--no-ansi
--show " /> ')" title="Copy section prompt for LLMs"> Copy Section
--sort " /> ')" title="Copy section prompt for LLMs"> Copy Section
--source " /> ')" title="Copy section prompt for LLMs"> Copy Section
--source-mode " /> ')" title="Copy section prompt for LLMs"> Copy Section
--specifier-types " /> ')" title="Copy section prompt for LLMs"> Copy Section
--help
Site Src Content Docs Command List (`site/src/content/docs/command/list.mdx`)
title: list
import { Badge } from "@astrojs/starlight/components";
import ConfigOption from "@partials/option/config.mdx";
import DependenciesOption from "@partials/option/dependencies.mdx";
import DependencyTypesOption from "@partials/option/dependency-types.mdx";
import HelpOption from "@partials/option/help.mdx";
import LogLevelsOption from "@partials/option/log-levels.mdx";
import NoAnsiOption from "@partials/option/no-ansi.mdx";
import QuoteFilters from "@partials/tips/quote-filters.mdx";
import ShowOption from "@partials/option/show-list.mdx";
import SortOption from "@partials/option/sort.mdx";
import SourceOption from "@partials/option/source.mdx";
import SourceModeOption from "@partials/option/source-mode.mdx";
import SpecifierTypesOption from "@partials/option/specifier-types.mdx";
List all dependencies in your monorepo with their versions and locations. Shows which dependencies have mismatches, are ignored, or follow your rules. Use this to explore what's installed before running lint or fix.
Examples
# Sort dependencies by how many times they are used
syncpack list --sort count
# Show every instance of each dependency, not just their names
syncpack list --show instances
# Show dependencies ignored in your syncpack config
syncpack list --show ignored
# Show highest level of detail
syncpack list --show all
# Choose only some values
syncpack list --show hints,statuses
# List all "peerDependencies"
syncpack list --dependency-types peer
# List all types packages
syncpack list --dependencies '@types/**'
# List instances of an exact version being used as a peer dependency
syncpack list --specifier-types exact --show instances --dependency-types peer
# See more examples
syncpack list --help
# See a short summary of options
syncpack list -hOptions
--config " /> ')" title="Copy section prompt for LLMs"> Copy Section
--dependencies " /> ')" title="Copy section prompt for LLMs"> Copy Section
--dependency-types " /> ')" title="Copy section prompt for LLMs"> Copy Section
--log-levels " /> ')" title="Copy section prompt for LLMs"> Copy Section
--no-ansi
--show " /> ')" title="Copy section prompt for LLMs"> Copy Section
--sort " /> ')" title="Copy section prompt for LLMs"> Copy Section
--source " /> ')" title="Copy section prompt for LLMs"> Copy Section
--source-mode " /> ')" title="Copy section prompt for LLMs"> Copy Section
--specifier-types " /> ')" title="Copy section prompt for LLMs"> Copy Section
--help
Site Src Content Docs Command Update (`site/src/content/docs/command/update.mdx`)
title: update sidebar: badge: Updated
import { Badge } from "@astrojs/starlight/components";
import CheckOption from "@partials/option/check.mdx";
import ConfigOption from "@partials/option/config.mdx";
import DependenciesOption from "@partials/option/dependencies.mdx";
import DependencyTypesOption from "@partials/option/dependency-types.mdx";
import DryRunOption from "@partials/option/dry-run.mdx";
import HelpOption from "@partials/option/help.mdx";
import InteractiveOption from "@partials/option/interactive.mdx";
import LogLevelsOption from "@partials/option/log-levels.mdx";
import NoAnsiOption from "@partials/option/no-ansi.mdx";
import NoCacheOption from "@partials/option/no-cache.mdx";
import QuoteFilters from "@partials/tips/quote-filters.mdx";
import ShowOption from "@partials/option/show-list.mdx";
import SortOption from "@partials/option/sort.mdx";
import SourceOption from "@partials/option/source.mdx";
import SourceModeOption from "@partials/option/source-mode.mdx";
import SpecifierTypesOption from "@partials/option/specifier-types.mdx";
import TargetOption from "@partials/option/target.mdx";
Update dependencies in your monorepo to newer versions from the npm registry. Checks for available updates and modifies package.json files (and pnpm-workspace.yaml catalog entries when present) to use them. Unlike fix which synchronises versions across packages, update fetches the latest published versions. Use --target to control update strategy (latest, minor, patch), or define updateGroups for per-dependency control. Versions newer than minimumReleaseAge are excluded by default to reduce supply chain attack risk.
Examples
# Accept any update in latest (x.x.x)
syncpack update --target latest
# Only update minor versions (1.x.x)
syncpack update --target minor
# Only update patch versions (1.2.x)
syncpack update --target patch
# Pick which updates to apply through an interactive prompt
syncpack update --interactive
# Interactively pick from patch updates only
syncpack update --interactive --target patch
# Interactively pick which @aws-sdk packages to update
syncpack update --interactive --dependencies '@aws-sdk/**'
# Check for outdated dependencies in one package
syncpack update --check --source 'packages/pingu/package.json'
# Update dependencies and devDependencies in the whole monorepo
syncpack update --dependency-types dev,prod
# Update only pnpm catalog entries in pnpm-workspace.yaml
syncpack update --dependency-types pnpmCatalog
# Update only the named pnpm catalog 'react18'
syncpack update --dependency-types 'pnpmCatalog:react18'
# Only update dependencies with a semver range specifier (^, ~, etc.)
syncpack update --specifier-types range
# Update dependencies where name exactly matches 'react'
syncpack update --dependencies 'react'
# Update dependencies where name contains 'react'
syncpack update --dependencies '**react**'
# Update dependencies with the '@aws-sdk' scope
syncpack update --dependencies '@aws-sdk/**'
# See more examples
syncpack update --help
# See a short summary of options
syncpack update -hOptions
--check
--config " /> ')" title="Copy section prompt for LLMs"> Copy Section
--dependencies " /> ')" title="Copy section prompt for LLMs"> Copy Section
--dependency-types " /> ')" title="Copy section prompt for LLMs"> Copy Section
--dry-run
--interactive
--log-levels " /> ')" title="Copy section prompt for LLMs"> Copy Section
--no-ansi
--no-cache
--source " /> ')" title="Copy section prompt for LLMs"> Copy Section
--source-mode " /> ')" title="Copy section prompt for LLMs"> Copy Section
--specifier-types " /> ')" title="Copy section prompt for LLMs"> Copy Section
--target " /> ')" title="Copy section prompt for LLMs"> Copy Section
--help
Site Src Content Docs Config Custom Types (`site/src/content/docs/config/custom-types.mdx`)
title: customTypes sidebar: badge: Updated
import { Badge } from "@astrojs/starlight/components";
import Details from "@site/components/details.astro";
Extend syncpack to manage other parts of package.json files than those provided by default.
Custom types behave indentically to the default dependency types (such as prod or peer). When you define a custom type, you are adding to the list of valid names that can be passed to the:
--dependency-typesCLI optiondependencyTypesproperty of Version Groups, Semver Groups, and Dependency Groups.
This is how the default dependency types are defined:
{
"$schema": "./node_modules/syncpack/schema.json",
"customTypes": {
"dev": {
"strategy": "versionsByName",
"path": "devDependencies"
},
"local": {
"strategy": "name~version",
"namePath": "name",
"path": "version"
},
"overrides": {
"strategy": "versionsByName",
"path": "overrides"
},
"peer": {
"strategy": "versionsByName",
"path": "peerDependencies"
},
"pnpmOverrides": {
"strategy": "versionsByName",
"path": "overrides",
"source": "PnpmWorkspace"
},
"prod": {
"strategy": "versionsByName",
"path": "dependencies"
},
"resolutions": {
"strategy": "versionsByName",
"path": "resolutions"
}
}
}Pick a strategy below based on the shape of your data.
`name@version`
A single string combining name and version, separated by @.
{
"packageManager": "[email protected]"
}{
"customTypes": {
"packageManager": {
"strategy": "name@version",
"path": "packageManager"
}
}
}\[name\]
The name of the new dependency type you are adding to syncpack. Syncpack ships with built-in types like prod, dev, and peer; defining a custom type adds your chosen name to that list, ready to be referenced from:
--dependency-typesversionGroup.dependencyTypessemverGroup.dependencyTypesdependencyGroup.dependencyTypes
\[name\].path
The location in each package.json of the "name@version" string. Use dot notation for nested properties (eg. packageManager, some.nested.property).
\[name\].strategy
Must be "name@version".
`name~version`
The name and version live at two separate paths. Both must point directly to string values, not to a containing object.
{
"devEngines": {
"runtime": {
"name": "node",
"version": "22.11.0"
}
}
}{
"customTypes": {
"devEnginesRuntime": {
"strategy": "name~version",
"namePath": "devEngines.runtime.name",
"path": "devEngines.runtime.version"
}
}
}A common mistake is pointing path at the containing object (devEngines.runtime) and namePath at name relative to it. Both paths are absolute from the package.json root and must resolve to strings.
\[name\]
The name of the new dependency type you are adding to syncpack. Syncpack ships with built-in types like prod, dev, and peer; defining a custom type adds your chosen name to that list, ready to be referenced from:
--dependency-typesversionGroup.dependencyTypessemverGroup.dependencyTypesdependencyGroup.dependencyTypes
\[name\].path
The location in each package.json of the version string. Absolute from the package.json root; must point to a string.
\[name\].namePath
The location in each package.json of the dependency name. Absolute from the package.json root; must point to a string.
\[name\].strategy
Must be "name~version".
`version`
A bare version string with no name in the data. The custom type's key is used as the dependency name.
{
"engines": {
"node": "22.11.0"
}
}{
"customTypes": {
"node": {
"strategy": "version",
"path": "engines.node"
}
}
}Here the dependency is reported as node because that is the custom type's key.
\[name\]
The name of the new dependency type you are adding to syncpack. Syncpack ships with built-in types like prod, dev, and peer; defining a custom type adds your chosen name to that list, ready to be referenced from:
--dependency-typesversionGroup.dependencyTypessemverGroup.dependencyTypesdependencyGroup.dependencyTypes
For the version strategy specifically, this name is also used as the dependency name in reports and grouping (since the data has no name field of its own).
\[name\].path
The location in each package.json of the version string. Use dot notation for nested properties (eg. engines.node).
\[name\].strategy
Must be "version".
`versionsByName`
A typical dependency object where keys are package names and values are version strings.
{
"dependencies": {
"pnpm": "10.10.0",
"prettier": "3.5.3"
}
}{
"customTypes": {
"prod": {
"strategy": "versionsByName",
"path": "dependencies"
}
}
}\[name\]
The name of the new dependency type you are adding to syncpack. Syncpack ships with built-in types like prod, dev, and peer; defining a custom type adds your chosen name to that list, ready to be referenced from:
--dependency-typesversionGroup.dependencyTypessemverGroup.dependencyTypesdependencyGroup.dependencyTypes
\[name\].path
The location in each package.json of the { "name": "version" } object. Use dot notation for nested properties (eg. dependencies, pnpm.overrides).
\[name\].strategy
Must be "versionsByName".
Site Src Content Docs Config Dependency Groups (`site/src/content/docs/config/dependency-groups.mdx`)
title: dependencyGroups
import { Badge } from "@astrojs/starlight/components";
import Packages from "@partials/group-config/packages.mdx";
import Dependencies from "@partials/group-config/dependencies.mdx";
import DependencyTypes from "@partials/group-config/dependency-types.mdx";
import SpecifierTypes from "@partials/group-config/specifier-types.mdx";
import Label from "@partials/group-config/label.mdx";
Allow many dependencies to be interpreted as one.
Example
Treat all dependencies from the AWS SDK for JavaScript as if they were all instances of a single dependency called aws-sdk-dependencies.
{
"dependencyGroups": [
{
"dependencies": ["@aws-sdk/**"],
"aliasName": "aws-sdk-dependencies",
},
],
}With the above config: "@aws-sdk/core", "@aws-sdk/middleware-logger" etc will be treated as if they were one dependency, so any differences in their versions will be caught in the usual way.
Configuration
aliasName
The name to use in place of the originals when referring to this group of merged dependencies.
When assigning this new dependency to version/semver groups etc, use the aliasName instead of the original name.
dependencies
dependencyTypes
specifierTypes
label
packages
Site Src Content Docs Config Format Bugs (`site/src/content/docs/config/format-bugs.mdx`)
title: formatBugs
import ConfigOnly from "@partials/tips/config-only.mdx";
When using the format command, enables formatting of the bugs field of package.json into a shorthand format.
Default value
{
"formatBugs": false
}Site Src Content Docs Config Format Repository (`site/src/content/docs/config/format-repository.mdx`)
title: formatRepository
When using the format command, enables formatting of the repository field of package.json into a shorthand format.
Default value
{
"formatRepository": false
}:::note
There is no equivalent CLI Option for this configuration.
:::
Site Src Content Docs Config Indent (`site/src/content/docs/config/indent.mdx`)
title: indent
When syncpack writes to package.json files, determines which characters to indent the JSON with.
Default value
{
"indent": " "
}Site Src Content Docs Config Max Concurrent Requests (`site/src/content/docs/config/max-concurrent-requests.mdx`)
title: maxConcurrentRequests
When using the update command, the maximum number of HTTP requests to the npm registry to keep in-flight at any given time.
Default value
{
"maxConcurrentRequests": 12
}Site Src Content Docs Config Minimum Release Age (`site/src/content/docs/config/minimum-release-age.mdx`)
title: minimumReleaseAge sidebar: badge: New
When using the update command, the minimum age (in minutes) a published version must reach before syncpack will consider it as an available update. Reduces supply chain attack risk by ignoring versions that have been on the registry for less time than the configured window. Most malicious releases are detected and unpublished within an hour.
When this option is omitted from the rcfile, syncpack reads minimumReleaseAge from the project's pnpm-workspace.yaml if present. When neither is set, it defaults to 1440 (one day). Setting 0 disables the filter.
Default Value
{
"minimumReleaseAge": 1440
}Examples
Wait one week before considering a published version:
{
"minimumReleaseAge": 10080
}Disable the filter and consider all published versions:
{
"minimumReleaseAge": 0
}Inherit the value already configured for pnpm by omitting it from the rcfile:
minimumReleaseAge: 1440Site Src Content Docs Config Severity (`site/src/content/docs/config/severity.mdx`)
title: severity sidebar: badge: New
import { Aside } from "@astrojs/starlight/components";
import { KEYS, GROUP_LABELS, GROUP_LINKS } from "@partials/severity/keys.js";
Every status code syncpack assigns has a default treatment: some can be auto-fixed and others are errors or warnings that need to be fixed manually. The optional severity map on a version group lets you override that behaviour for the dependencies the group matches.
{
"versionGroups": [
{
"label": "Don't auto-delete banned dependencies, fail CI instead",
"dependencies": ["lodash", "moment"],
"isBanned": true,
"severity": {
"IsBanned": "error",
},
},
{
"label": "Override syncpack's refusal to rewrite .version",
"dependencies": ["my-pkg"],
"dependencyTypes": ["local"],
"pinVersion": "1.0.0",
"severity": {
"RefuseToPinLocal": "fix",
},
},
{
"label": "Don't auto-fix missing catalog entries, warn instead",
"policy": "catalog",
"severity": {
"MissingFromCatalog": "warn",
},
},
],
}Possible Values
| Value | fix |
lint |
|---|---|---|
"fix" |
Fix, exit 0 | Display error, exit 1 |
"warn" |
Display warning, exit 0 | Display warning, exit 0 |
"error" |
Do not fix, display error, exit 1 | Display error, exit 1 |
Default Values
When a status has no explicit entry in the map, syncpack falls back to a default appropriate for its kind:
| Status Code Type | Configurable? | Default severity |
|---|---|---|
| Valid | no | n/a |
| Fixable | yes | "fix" |
| Unfixable | no | "error" |
| RefuseToPinLocal / RefuseToSnapLocal | yes | "warn" |
| Suspect | no | "warn" |
| Conflict (between version + semver groups) | no | "error" |
strict: true escalates every unconfigured Suspect default from "warn" to "error". It does not touch Fixable defaults, and explicit severity always wins: "RefuseToPinLocal": "warn" stays "warn" even under strict: true.
Excluded Values
A few status codes are deliberately not configurable:
DiffersToNpmRegistryis owned byupdateGroups. Registry-update behaviour is tuned there, not via severity. Writing it as a severity key fails withInvalidSeverityKey.- Unfixable and Conflict statuses are always
"error". They represent ambiguity that severity cannot resolve: syncpack has no fix to apply and silencing them would hide real problems.
Site Src Content Docs Config Sort Az (`site/src/content/docs/config/sort-az.mdx`)
title: sortAz
When using the format command, determines which fields within package.json files should be sorted alphabetically. When the value is an Object, its keys are sorted alphabetically. When the value is an Array, its values are sorted alphabetically.
Default Value
{
"sortAz": [
"bin",
"contributors",
"dependencies",
"devDependencies",
"keywords",
"peerDependencies",
"resolutions",
"scripts"
]
}:::note
There is no equivalent CLI Option for this configuration.
:::
Site Src Content Docs Config Sort Exports (`site/src/content/docs/config/sort-exports.mdx`)
title: sortExports
When using the format command, enables sorting the exports property of package.json files.
By default, Syncpack will order properties according to the Node.js documentation for conditional exports.
Default Value
{
"sortExports": [
"types",
"node-addons",
"node",
"browser",
"module",
"import",
"require",
"svelte",
"development",
"production",
"script",
"default"
]
}Disable
Set to an empty array to disable.
{
"sortExports": []
}:::note
There is no equivalent CLI Option for this configuration.
:::
Site Src Content Docs Config Sort First (`site/src/content/docs/config/sort-first.mdx`)
title: sortFirst
When using the format command, determines which fields within package.json files should appear at the top, and in what order.
Default Value
{
"sortFirst": ["name", "description", "version", "author"]
}:::note
There is no equivalent CLI Option for this configuration.
:::
Site Src Content Docs Config Sort Packages (`site/src/content/docs/config/sort-packages.mdx`)
title: sortPackages
When using the format command, enables sorting the root properties of package.json in alphabetical order.
This pairs well with the sortFirst option, allowing you to ensure that eg. the name and version properties are always at the top of the file, with the other properties following in A-Z order.
Default Value
{
"sortPackages": true
}:::note
There is no equivalent CLI Option for this configuration.
:::
Site Src Content Docs Config Source Mode (`site/src/content/docs/config/source-mode.mdx`)
title: sourceMode sidebar: badge: New
Controls whether your source patterns (and --source CLI options) replace the patterns discovered from your package manager or are appended to them.
"replace"(default): your patterns replace workspace discovery entirely."extend": your patterns are appended after the discovered patterns fromworkspaces/pnpm-workspace.yaml/lerna.json.
{
"sourceMode": "extend",
"source": ["tools/scripts/package.json"]
}The CLI flag --source-mode <replace|extend> overrides whatever is set in the rcfile.
Discovered patterns are emitted first; your patterns are appended last, so gitignore-style negations such as !apps/legacy can exclude discovered entries.
Site Src Content Docs Config Source (`site/src/content/docs/config/source.mdx`)
title: source
import HowPackagesAreResolved from "@partials/how-packages-are-resolved.mdx";
import MonorepoNotEssentialTip from "@partials/tips/monorepo-not-essential.mdx";
If for some reason you do not want to use the same files as your package manager, you can use the source config to provide an alternative list of glob patterns to override which package.json files syncpack will operate on.
Polyrepos
In this example we have a directory on our machine called my-projects where we git clone all of the repositories we work on for our company.
Despite us not having a monorepo, a .syncpackrc.json placed alongside each git clone allows us to use syncpack to find and fix problems.
{
"source": ["./*/package.json", "./*/packages/*/package.json"]
}Site Src Content Docs Config Strict (`site/src/content/docs/config/strict.mdx`)
title: strict
Default Value
{
"strict": false
}Site Src Content Docs Config Syncpackrc (`site/src/content/docs/config/syncpackrc.mdx`)
title: .syncpackrc sidebar: order: 1
Syncpack searches the current directory for a:
.syncpackrcfile with no extension in JSON format.syncpackrcfile with the extension.json,.yaml,.yml,.js,.ts,.mjs, or.cjssyncpack.config.js,syncpack.config.ts,syncpack.config.mjs, orsyncpack.config.cjsfileconfig.syncpackorsyncpackproperty inpackage.json.
A custom name and location can be provided instead, but it must have a file extension:
syncpack list --config ./config/syncpack.jsonYour config file only needs to define values for those you want to change from the defaults.
JSON
JSON is preferred as it is the fastest, without the overhead of calling out to Node.js and TypeScript.
{
"$schema": "./node_modules/syncpack/schema.json",
"indent": " "
}TypeScript
export default {
indent: " ",
} satisfies import("syncpack").RcFile;JavaScript
// @ts-check
/** @type {import("syncpack").RcFile} */
const config = {
indent: " ",
};
module.exports = config;Site Src Content Docs Guide Migrate V14 (`site/src/content/docs/guide/migrate-v14.mdx`)
title: Migrate to 14
npm install --save-dev syncpackCommand Changes
`list-mismatches` → `lint`
list-mismatches and lint-semver-ranges have been merged into a single lint command which checks whether every specifier matches the semver group and version group they belong to. The lint command no longer checks formatting, which is now handled by syncpack format --check.
# v13
syncpack list-mismatches --types prod,dev
# v14
syncpack lint --dependency-types prod,dev`lint-semver-ranges` → `lint`
list-mismatches and lint-semver-ranges have been merged into a single lint command which checks whether every specifier matches the semver group and version group they belong to. The lint command no longer checks formatting, which is now handled by syncpack format --check. It's no longer possible to manage semver ranges without also checking version mismatches, because the two things are so closely linked. Changes to semver ranges affect which versions are considered valid and can indirectly cause version mismatches, so they are now always checked and changed together via the lint and fix commands.
# v13
syncpack lint-semver-ranges
# v14
syncpack lint`fix-mismatches` → `fix`
fix-mismatches and set-semver-ranges have been merged into a single fix command which autofixes issue found by syncpack lint. The fix command no longer fixes formatting, which is now handled by syncpack format.
# v13
syncpack fix-mismatches
# v14
syncpack fix`set-semver-ranges` → `fix`
fix-mismatches and set-semver-ranges have been merged into a single fix command which autofixes issue found by syncpack lint. The fix command no longer fixes formatting, which is now handled by syncpack format. It's no longer possible to manage semver ranges without also checking version mismatches, because the two things are so closely linked. Changes to semver ranges affect which versions are considered valid and can indirectly cause version mismatches, so they are now always checked and changed together via the lint and fix commands.
# v13
syncpack set-semver-ranges
# v14
syncpack fix`prompt` → Removed
The prompt command is an interactive prompt which lists all current issues which syncpack can't fix automatically. It is not yet available in v14 and will be added at a later date. Syncpack can't automatically fix mismatches between specifiers it does not support, which are usually specifiers which are not semver, such as pnpm overrides, or complex semver specifiers like ^1.2.3 || ^2.0.0.
# v13
syncpack prompt
# v14
# Not yet implementedCLI Option Changes
`--types` → `--dependency-types`
Renamed for consistency and also to differentiate it from other types such as specifier types.
# v13
syncpack list-mismatches --types prod,dev
# v14
syncpack lint --dependency-types prod,dev`--specs` → `--specifier-types`
Renamed for consistency.
# v13
syncpack format --specs exact,range
# v14
syncpack format --specifier-types exact,range`--filter` → `--dependencies`
This has been renamed to dependencies to match the equivalent property of version groups and semver groups. Regular expressions are no longer supported and instead a glob pattern should be provided in the same way as they are for version groups and semver groups.
# v13
syncpack list-mismatches --filter "^@types\/.+"
# v14
syncpack lint --dependencies "@types/**"Config Changes
`dependencyTypes` removed
The dependencyTypes config has been removed in favour of using versionGroups config, which achieves the same result:
{
// Removed in v14
"dependencyTypes": ["prod", "dev", "peer"],
// Use instead
"versionGroups": [
{
"label": "Ignore everything except dependencies, devDependencies, and peerDependencies",
"dependencies": ["!prod", "!dev", "!peer"],
"isIgnored": true,
},
],
}Or use the --dependency-types CLI option to filter on an ad hoc basis:
syncpack lint --dependency-types prod,dev,peer`specifierTypes` removed
The specifierTypes config has been removed in favour of using versionGroups config, which achieves the same result:
{
// Removed in v14
"specifierTypes": ["exact", "range"]
// Use instead
"versionGroups": [
{
"label": "Ignore everything except exact (1.2.3) or range (>=1.2.3, ~1.2.3 etc) specifier types",
"specifierTypes": ["!exact", "!range"]
"isIgnored": true,
},
],
}Or use the --specifier-types CLI option to filter on an ad hoc basis:
syncpack format --specifier-types exact,range`lintFormatting` removed
The lint command no longer checks formatting, only version mismatches, so the lintFormatting option is no longer needed. If you don't want to lint or fix formatting, you can just not use syncpack format or syncpack format --check.
format handles formatting, lint and fix handle version issues.
{
// Removed in v14
"lintFormatting": false,
}# Check if formatting needed (exit 1 if needed)
syncpack format --check
# Safely see what formatting fixes would look like
syncpack format --dry-run
# Write formatting fixes to disk
syncpack format`lintSemverRanges` removed
It's no longer possible to manage semver ranges without also checking version mismatches, because the two things are so closely linked. Changes to semver ranges affect which versions are considered valid and can indirectly cause version mismatches, so they are now always checked and changed together via the lint and fix commands.
V14 will always lint semver ranges when checking for version mismatches, but this will only apply to you if you have semverGroups defined. Let's say your project has react installed in three places: two of them use exact versions (19.1.0 and 19.1.1) and one of them belongs to a Semver Group which requires a ^ range so has a version of ^19.1.0. Syncpack will synchronise these versions so that the highest version of 19.1.1 is used everywhere, while respecting the Semver Group requirement of ^19.1.1 being used for the member of that group.
{
// Removed in v14
"lintSemverRanges": false,
}`lintVersions` → Always enabled
It's no longer possible to manage semver ranges without also checking version mismatches, because the two things are so closely linked. Changes to semver ranges affect which versions are considered valid and can indirectly cause version mismatches, so they are now always checked and changed together via the lint and fix commands.
This option is redundant in V14.
{
// Removed in v14
"lintVersions": false,
}Migrating from older versions
Version 11.2.1
`workspace` dependency type renamed to `local`
The workspace dependency type has been renamed to local for clarity.
# v11.2.0 and earlier
syncpack list --types prod,workspace
# v14
syncpack lint --dependency-types prod,localVersion 9.0.0
CLI Options Replaced
Individual boolean flags replaced with --dependency-types option:
# v8
syncpack list --prod --dev --peer
# v14
syncpack lint --dependency-types prod,dev,peerThe following flags were removed:
-p, --prod-d, --dev-P, --peer-R, --resolutions-o, --overrides-O, --pnpmOverrides-w, --workspace
Config Changes
Individual boolean properties replaced with versionGroups configuration:
// v8
{
"dev": true,
"overrides": false,
"peer": true,
"pnpmOverrides": false,
"prod": true,
"resolutions": false,
"workspace": true
}
// v14 (use versionGroups instead)
{
"versionGroups": [
{
"label": "Ignore overrides",
"dependencyTypes": ["overrides", "pnpmOverrides", "resolutions"],
"isIgnored": true
}
]
}Version 8.0.0
pnpm overrides renamed
The --overrides option now refers to npm overrides. pnpm users must use --pnpmOverrides instead.
# v7 (pnpm users)
syncpack list --overrides
# v14 (pnpm users)
syncpack list --dependency-types pnpmOverrides
# v14 (npm users)
syncpack list --dependency-types overridesContext: v6.0.0 originally added --overrides for pnpm but read from the wrong property. npm later added their own .overrides property, so v8 split these into separate options.
Version 7.0.0
Workspace dependency syncing enabled by default
Syncpack now syncs versions of locally developed packages by default. If package A depends on package B (both in your monorepo), syncpack will fix A's dependency to match B's actual version.
In v14, disable this behavior using versionGroups:
{
"versionGroups": [
{
"label": "Ignore .version properties of local packages",
"dependencyTypes": ["local"],
"isIgnored": true,
},
],
}Or exclude local when using CLI flags:
# v14
syncpack lint --dependency-types '!local'Version 6.0.0
`resolutions` and `overrides` enabled by default
Yarn's resolutions and pnpm's overrides fields are now processed by default.
In v14, exclude them using versionGroups:
{
"versionGroups": [
{
"label": "Ignore overrides",
"dependencyTypes": ["resolutions", "overrides", "pnpmOverrides"],
"isIgnored": true,
},
],
}Or via CLI:
# v14
syncpack lint --dependency-types dev,peer,prodVersion 3.0.0
`--source` option changed
Package locations now specified with repeatable --source option instead of positional arguments:
# v2
syncpack list './package.json' './packages/*/package.json'
# v14
syncpack list --source './package.json' --source './packages/*/package.json'Site Src Content Docs Guide Migrate V15 (`site/src/content/docs/guide/migrate-v15.mdx`)
title: Migrate to 15 sidebar: badge: New
npm install --save-dev syncpack`pnpmOverrides` now reads `pnpm-workspace.yaml`
The default pnpmOverrides dependency type now reads overrides from pnpm-workspace.yaml instead of pnpm.overrides in package.json. This matches pnpm's current convention for managing overrides.
Restoring the legacy behaviour
If your overrides still live in package.json under pnpm.overrides, define pnpmOverridesLegacy in your config to point at the legacy location:
{
"customTypes": {
"pnpmOverridesLegacy": {
"strategy": "versionsByName",
"path": "pnpm.overrides"
}
}
}The default pnpmOverrides continues to manage the YAML location.
Site Src Content Docs Guide Peer Dependencies (`site/src/content/docs/guide/peer-dependencies.mdx`)
title: Peer Dependencies
If any of your packages define peerDependencies (find out with syncpack list --dependency-types peer) it's really important that we understand them as they have a very different role.
dependencies tend to be exact (1.2.3) or clamped within the patch ~1.2.0 or sometimes even minor ^1.2.0 ranges. They're narrower in scope because there we are a consumer and we want higher confidence over knowing what we are running.
peerDependencies tend to be far broader in scope because in those scenarios we are a provider and we want our package to be suitable for as many consuming projects as possible. These versions tend to span entire majors (^1) and sometimes multiple majors (>=6.0.0 <9.0.0).
Why this matters
Unless your project is well-organised using Version Groups, it is very likely that at some point you will see a version mismatch because a peer dependency is not equal to a production dependency.
Here's a common example:
- One of the packages you develop is an ESLint Plugin and in its
peerDependenciesyou define a range of"eslint": ">=6.0.0 <9.0.0"for the ESLint versions it is compatible with. - Elsewhere you have
"eslint": "8.53.0"installed underdevDependenciesbecause you use ESLint to lint the monorepo.
Syncpack will report a version mismatch because ESLint is referenced twice with wildly different versions.
That we don't consider this particular mismatch to be a problem is domain knowledge about our specific project. Syncpack needs us to share with it that domain knowledge via its Configuration file.
Site Src Content Docs Guide Whats New (`site/src/content/docs/guide/whats-new.mdx`)
title: What's New sidebar: badge: New
import { Badge } from "@astrojs/starlight/components";
Range Only version group
semverRangeOnly enforces a consistent semver range prefix (^, ~, exact) across instances without syncing the version numbers themselves.
Update summary lists only accepted updates
The summary printed after choosing updates to apply using syncpack update --interactive now lists only the updates you actually applied, rather than every candidate found.
Optionally override autofix per status code
The severity map on a version group lets you disable autofixing on a per-status code basis, and instead error or warn.
{
"versionGroups": [
{
"dependencies": ["lodash"],
"isBanned": true,
"severity": { "IsBanned": "warn" },
},
],
}Extend source patterns instead of replacing
A new sourceMode option (and --source-mode flag) can override the default of "replace" to use "extend" to append your package.json glob patterns to those discovered from workspaces / pnpm-workspace.yaml / lerna.json.
Non-`package.json` files as sources
A fairly niche feature request, but the source option now accepts other .json filenames than package.json when explicitly listed. Some bugs with Glob and gitignore matching were also fixed in this release.
Update Groups
updateGroups control how and whether various parts of your monorepo should be updated from the npm registry. See Targeted and Ignored.
{
"updateGroups": [
{ "dependencies": ["storybook", "@storybook/**"], "target": "patch" },
{ "dependencyTypes": ["dev"], "target": "minor" },
{ "dependencyTypes": ["peer"], "isIgnored": true },
],
}When both the CLI's --target and a group's target apply, the stricter of the two wins.
Interactive update picker
syncpack update --interactive opens a keyboard-driven picker so you choose which updates to apply. Use space to toggle, a to toggle all, enter to confirm.
Registry response caching
Registry responses are cached on disk for 30 minutes by default to avoid repeat network calls. Pass --no-cache to bypass for the current run.
pnpm and Bun catalogs
Full support for the catalog: protocol. Define a dependency's version once and have every package consume it via catalog: or catalog:{name}.
- New Catalog version group enforces that matched dependencies live in a catalog and are consumed via the protocol.
- Syncpack writes catalog entries to
pnpm-workspace.yaml(pnpm) or the rootpackage.json(Bun), creating the implicitdefaultcatalog at fix time when one does not yet exist. - Filter updates by catalog:
syncpack update --dependency-types pnpmCatalog, or by named catalog:pnpmCatalog:react18.
minimumReleaseAge
minimumReleaseAge excludes versions published more recently than the configured window, reducing supply-chain attack risk. Defaults to 1440 minutes (one day). Inherits from pnpm-workspace.yaml when unset; set 0 to disable.
pnpmOverrides reads from pnpm-workspace.yaml
Breaking change. The default pnpmOverrides dependency type now reads overrides from pnpm-workspace.yaml instead of pnpm.overrides in package.json. See the v15 migration guide for how to restore the legacy behaviour with pnpmOverridesLegacy.
Site Src Content Docs Reference Dependency Types (`site/src/content/docs/reference/dependency-types.mdx`)
title: Dependency Types slug: dependency-types
import DefaultDependencyTypes from "@partials/default-dependency-types.mdx";
Dependency types refer to the different locations in package.json files where dependencies can be defined.
Default Values
The default dependency types in syncpack are the ones defined by npm, pnpm, and yarn:
Catalog Names
Catalog dependency types are added automatically when syncpack detects pnpm catalogs in pnpm-workspace.yaml or Bun catalogs in the root package.json.
| Name | Source | When |
|---|---|---|
pnpmCatalog |
pnpm-workspace.yaml catalog |
the pnpm default catalog has entries |
pnpmCatalog:<name> |
pnpm-workspace.yaml catalogs.<name> |
one per named pnpm catalog |
bunCatalog |
root package.json catalog |
the Bun default catalog is present |
bunCatalog:<name> |
root package.json catalogs.<name> |
one per named Bun catalog |
Bun also recognises workspaces.catalog and workspaces.catalogs.<name>. These names work everywhere a dependency type is accepted.
syncpack lint --dependency-types pnpmCatalog
syncpack list --dependency-types 'pnpmCatalog:react18'Custom Values
You can extend the above list by defining your own custom types, such as:
- Engine versions (
engines) - Package manager versions (
packageManager) - Any other nested property in package.json
- Properties in
pnpm-workspace.yaml(viasource: "PnpmWorkspace")
Using Dependency Types
Dependency types can be specified in these contexts:
Command Line Filtering
Use the --dependency-types option to target specific types in commands:
# Only check production dependencies
syncpack lint --dependency-types prod
# Check both production and development dependencies
syncpack lint --dependency-types prod,dev
# Check everything except peer dependencies
syncpack lint --dependency-types '!peer'Configuration
Dependency types can be used to target and filter:
- Version Groups - Carve out specific version policies
- Semver Groups - Define which semver ranges to use with specific dependencies
- Dependency Groups - Merge and alias families of dependencies as one
Site Src Content Docs Reference Glossary (`site/src/content/docs/reference/glossary.mdx`)
title: Glossary slug: glossary
Catalog Definition
The entry in a pnpm or Bun catalog that holds the actual version specifier for a dependency. Catalog definitions live in pnpm-workspace.yaml for pnpm or under /catalog, /catalogs/{name}, /workspaces/catalog, or /workspaces/catalogs/{name} in the root package.json for Bun. Consumer packages reference a definition with the catalog: or catalog:{name} protocol instead of writing the version directly.
Complex Semver
A semver version with conditional logic, such as ^1.2.3-alpha || ~1.2.3-rc.1.
Custom Type
A user-defined configuration that extends syncpack to manage parts of your package.json files beyond the default dependency types. Custom types behave identically to the default dependency types (such as prod or peer) but allow you to manage additional sections like engines, packageManager, or arbitrary nested properties.
Dependency Group
A collection of related dependencies that are merged together and treated as one. Dependencies can be grouped by name pattern, package location, or dependency type.
Dependency Type
Refers to the path/location within package.json files where dependencies are defined. The standard types include prod (dependencies), dev (devDependencies), peer (peerDependencies), overrides, pnpmOverrides, resolutions, and local (the package's own version property).
Dependency
A package that your project relies on. In syncpack, this refers to an npm package that's listed in any of the dependency fields of your package.json files. A dependency has a name and a version specifier.
Instance
A specific occurrence of a dependency in your monorepo, for example:
- There are 4 packages in your monorepo (A, B, C, and D).
- A, B, C, and D all depend on
uuid. - A, B, and C each have it under
dependencies(3x). - D has it under
devDependenciesandpeerDependencies(2x).
There are 5 "instances" of the 1 "dependency" uuid.
Local Instance
A specific occurrence of a dependency in your monorepo that is defined by the package's own version property. This is a package developed internally within your monorepo.
Package
A module within your monorepo defined by a package.json file. In a monorepo, you typically have multiple packages that may depend on each other and on external dependencies.
Rcfile
A configuration file for syncpack (typically .syncpackrc, .syncpackrc.js, .syncpackrc.json, etc.) that defines how dependencies should be managed. This includes settings like version groups, semver groups, formatting options, and more.
Semver Group
A configuration that defines how semver ranges should be formatted for a specific set of dependencies. For example, you might want production dependencies to use exact versions (1.2.3) while development dependencies use caret ranges (^1.2.3).
Semver Number
The version number portion of the version specifier, such as 1.2.3, excluding any Semver Range that may be present.
Semver Range
A pattern that specifies which versions of a dependency are acceptable. Common ranges include exact (1.2.3), caret (^1.2.3, which allows compatible minor and patch updates), and tilde (~1.2.3, which allows compatible patch updates).
Semver
Semantic Versioning, a versioning scheme that uses a three-part number (MAJOR.MINOR.PATCH) to convey meaning about the underlying changes. Major versions indicate breaking changes, minor versions indicate new features without breaking changes, and patch versions indicate bug fixes.
Severity
The user-tunable treatment of a Status Code on a particular instance: fix (auto-fix it), warn (surface but exit 0), or error (surface and exit 1). Set via the severity map on a Version Group. See severity for the full semantics.
Simple Semver
A typical semver version such as 1.2.3, ^1.2.3, or 1.2.3.alpha.
Source Mode
Controls how user-supplied source patterns (in the rcfile or via --source) combine with workspace discovery. "replace" (default) discards discovered patterns and uses only the user patterns; "extend" appends user patterns after discovered ones, letting gitignore-style negations such as !apps/legacy exclude discovered entries. See sourceMode.
Specifier
The full version string for a dependency, including any prefixes or range indicators. Examples include ^1.2.3, ~1.2.3, >=1.0.0, 1.x, and *.
Specifier Type
A categorization of version specifiers based on their format. Types include exact (1.2.3), range (^1.2.3), latest (*), tag (alpha), and others like file, git, or url.
Status Code
A code assigned by syncpack to each dependency instance that indicates its validation status. Status codes help identify issues such as version mismatches, banned dependencies, or configurations that need attention.
Update Group
A configuration that controls which registry updates are eligible for a specific set of dependency instances. Update groups can clamp matched instances to patch-only or minor-only updates, or skip them from update consideration entirely. They affect only the update command and are independent of version groups and semver groups.
Update Target
The greediness of an update run. "patch" allows only same major and minor with a higher patch; "minor" allows same major with a higher minor or patch; "latest" allows any newer version including major bumps. Set via the --target CLI flag or the target field on an Update Group. When both apply to the same instance, the stricter of the two wins (patch < minor < latest).
Version Group
A configuration object that defines a partition of your monorepo with its own versioning policy. Version groups let you create separate rules for different sections of your project, such as pinning specific dependencies to exact versions, banning certain dependencies, or ensuring dependencies follow the version used by a specific package.
Workspace
A collection of packages managed together in a monorepo. Workspaces are typically defined by your package manager (npm, Yarn, pnpm) and help syncpack locate all the package.json files in your project.
Site Src Content Docs Reference Specifier Types (`site/src/content/docs/reference/specifier-types.mdx`)
title: Specifier Types slug: specifier-types
Specifier types categorise the different formats a version specifier can have in package.json files.
They can be used in version groups and other configuration to apply specific rules to dependencies based on how their versions are specified, to ban unsupported versions or check for updates for only exact versions for example.
All Values
alias
A dependency that uses npm's alias syntax to reference a package under a different name.
Example: npm:@preact/compat
catalog
A dependency that uses the catalog: protocol to reference a version defined in a shared catalog.
Example: catalog:
exact
A dependency with a precise version number, including potential pre-release identifiers.
Examples: 1.2.3, 1.2.3-alpha, 1.2.3-rc.1
file
A dependency referencing a local file path on the filesystem.
Example: file:./path/to/package
link
A dependency that uses the link: protocol to reference a local path without installing it as a symlink via the package manager.
Example: link:../other-package
git
A dependency directly referencing a Git repository.
Example: git+https://github.com/user/repo.git
latest
A dependency that resolves to the latest available version. Includes wildcard patterns.
Examples: latest, *
major
A dependency specifier that only indicates the major version number.
Example: 1
minor
A dependency specifier that includes both major and minor version numbers.
Example: 1.2
missing
A local package.json with a missing version field
range
A dependency that uses standard semver range syntax with a complete version number.
Examples: ^1.2.3, ^1.2.3-alpha, ^1.2.3-rc.1
range-complex
A dependency that uses multiple ranges combined with logical operators.
Example: ^1.2.3-alpha || ~1.2.3-rc.1
range-major
A dependency that uses a range operator with only a major version.
Example: ^1
range-minor
A dependency that uses a range operator with major and minor versions.
Example: ^1.2
tag
A dependency referencing an npm distribution tag rather than a version.
Example: alpha
unsupported
A dependency with a version specifier that syncpack cannot parse or handle.
Example: wtf|#|broken
url
A dependency referencing a URL to a package distribution.
Example: https://example.com/package
workspace-protocol
A dependency that uses the workspace protocol for monorepo local references.
Example: workspace:*
Using Specifier Types
Specifier types can be used in various contexts within syncpack:
Command Line Filtering
Use the --specifier-types option to target dependencies with specific version formats:
# Only check dependencies with exact versions
syncpack lint --specifier-types exact
# Find dependencies using any kind of range
syncpack list --specifier-types range,range-major,range-minor
# Check everything except URL dependencies
syncpack lint --specifier-types '!url'Configuration
Specifier types can be used to target and filter Version Groups, to apply specific rules to dependencies based on their version format.
Site Src Content Docs Semver Groups Ignored (`site/src/content/docs/semver-groups/ignored.mdx`)
title: Ignored
import { Badge } from "@astrojs/starlight/components";
import Packages from "@partials/group-config/packages.mdx";
import Dependencies from "@partials/group-config/dependencies.mdx";
import DependencyTypes from "@partials/group-config/dependency-types.mdx";
import SpecifierTypes from "@partials/group-config/specifier-types.mdx";
import Label from "@partials/group-config/label.mdx";
Have syncpack ignore the semver ranges of these dependencies completely.
Configuration
isIgnored
{
"semverGroups": [
{
"packages": ["oops-moment", "workaround"],
"isIgnored": true
}
]
}dependencies
dependencyTypes
specifierTypes
label
packages
Site Src Content Docs Semver Groups With Range (`site/src/content/docs/semver-groups/with-range.mdx`)
title: With Range
import { Badge } from "@astrojs/starlight/components";
import Packages from "@partials/group-config/packages.mdx";
import Dependencies from "@partials/group-config/dependencies.mdx";
import DependencyTypes from "@partials/group-config/dependency-types.mdx";
import SpecifierTypes from "@partials/group-config/specifier-types.mdx";
import Label from "@partials/group-config/label.mdx";
Ensure all dependencies within this group have the specified semver range.
Configuration
range
Which of the Supported Ranges this group should use.
{
"semverGroups": [
{
"dependencies": ["@foo/**"],
"range": "~"
}
]
}dependencies
dependencyTypes
specifierTypes
label
packages
Site Src Content Docs Status Cannot Infer Catalog File (`site/src/content/docs/status/cannot-infer-catalog-file.mdx`)
title: CannotInferCatalogFile status: unfixable
import SeverityUnfixable from "@partials/severity/unfixable.mdx";
When this happens
- ✓ Instance is in a Catalog version group
- ✓ Project has 0 catalogs
- ✘ No recognised lock file (npm, yarn, or unknown package manager)
- ? Cannot infer whether to create
pnpm-workspace.yamlor rootpackage.json/catalog
Severity
Site Src Content Docs Status Depends On Invalid Local Package (`site/src/content/docs/status/depends-on-invalid-local-package.mdx`)
title: DependsOnInvalidLocalPackage status: unfixable
import SeverityUnfixable from "@partials/severity/unfixable.mdx";
When this happens
- ✓ Instance is in a Highest Semver or Lowest Semver version group
- ✘ Instance depends on a local package whose package.json version is not exact semver
- ? We can't know what the version should be
Severity
Site Src Content Docs Status Depends On Missing Catalog Definition (`site/src/content/docs/status/depends-on-missing-catalog-definition.mdx`)
title: DependsOnMissingCatalogDefinition status: suspect
import SeveritySuspect from "@partials/severity/suspect-default.mdx";
When this happens
- ✓ Instance uses the
catalog:protocol (barecatalog:orcatalog:{name}) - ✘ The referenced catalog does not exist OR the dependency name is not defined in it
Severity
Site Src Content Docs Status Depends On Missing Snap Target (`site/src/content/docs/status/depends-on-missing-snap-target.mdx`)
title: DependsOnMissingSnapTarget status: suspect
import SeveritySuspect from "@partials/severity/suspect-default.mdx";
When this happens
- ✓ Instance is in a Snapped To version group
- ✘ An instance of the same dependency was not found in any of the snapped to packages
- ! This is a misconfiguration resulting in this instance being orphaned
Severity
Site Src Content Docs Status Differs To Catalog (`site/src/content/docs/status/differs-to-catalog.mdx`)
title: DiffersToCatalog status: fixable
import SeverityTable from "@partials/severity/table-fixable.mdx";
When this happens
- ✓ Instance is in a Highest Semver or Lowest Semver version group
- ✓ One or more other instances use the
catalog:protocol - ✘ Instance does not use the
catalog:protocol - !
catalog:protocol wins
Severity
Configurable via severity on a Highest Semver or Lowest Semver version group.
Site Src Content Docs Status Differs To Highest Or Lowest Semver Minor (`site/src/content/docs/status/differs-to-highest-or-lowest-semver-minor.mdx`)
title: DiffersToHighestOrLowestSemverMinor status: fixable
import SeverityTable from "@partials/severity/table-fixable.mdx";
When this happens
- ✓ Instance is in a Same Minor version group with
preferVersionset - ✓ All instances share the same MAJOR version
- ✘ Instance's MAJOR.MINOR is not the highest (or lowest) MAJOR.MINOR in the group
How it's fixed
The instance is updated to match the preferred MAJOR.MINOR target. The range selection follows this priority:
- If instance has a With Range semver group with a preferred range which will not allow a version outside of the MAJOR.MINOR range to be installed, then use the preferred range
- If instance has no semver group and on-disk range does not allow a version outside of the MAJOR.MINOR range to be installed, then preserve the on-disk range
- Otherwise use
~(Same Minor policy wins over unsafe ranges)
Safe ranges are "" (Exact) and ~ (Patch).
Severity
Configurable via severity on a Same Minor version group.
Site Src Content Docs Status Differs To Highest Or Lowest Semver (`site/src/content/docs/status/differs-to-highest-or-lowest-semver.mdx`)
title: DiffersToHighestOrLowestSemver status: fixable
import SeverityTable from "@partials/severity/table-fixable.mdx";
When this happens
- ✓ Instance is in a Highest Semver or Lowest Semver version group
- ✘ Instance mismatches highest/lowest semver in its group
Severity
Configurable via severity on a Highest Semver or Lowest Semver version group.
Site Src Content Docs Status Differs To Local (`site/src/content/docs/status/differs-to-local.mdx`)
title: DiffersToLocal status: fixable
import SeverityTable from "@partials/severity/table-fixable.mdx";
When this happens
- ✓ Instance is in a Highest Semver or Lowest Semver version group
- ✘ Instance mismatches the version of its Local Instance
Severity
Configurable via severity on a Highest Semver or Lowest Semver version group.
Site Src Content Docs Status Differs To Npm Registry (`site/src/content/docs/status/differs-to-npm-registry.mdx`)
title: DiffersToNpmRegistry status: fixable
When this happens
- ✓ Instance is in a Highest Semver, Lowest Semver, or Range Only version group
- ✘ Instance is older than highest semver published to the registry
Severity
Not configurable via severity. Registry-update behaviour is controlled by updateGroups. Writing DiffersToNpmRegistry in a severity map fails with InvalidSeverityKey.
Only the update command surfaces this status; fix, lint, and list are unaffected by it.
Site Src Content Docs Status Differs To Pin (`site/src/content/docs/status/differs-to-pin.mdx`)
title: DiffersToPin status: fixable
import SeverityTable from "@partials/severity/table-fixable.mdx";
When this happens
- ✓ Instance is in a Pinned version group
- ✘ Instance mismatches its pinned version group
Severity
Site Src Content Docs Status Differs To Snap Target (`site/src/content/docs/status/differs-to-snap-target.mdx`)
title: DiffersToSnapTarget status: fixable
import SeverityTable from "@partials/severity/table-fixable.mdx";
When this happens
- ✓ Instance is in a Snapped To version group
- ✘ Instance mismatches the matching snapTo instance
Severity
Configurable via severity on a Snapped To version group.
Site Src Content Docs Status Invalid Local Version (`site/src/content/docs/status/invalid-local-version.mdx`)
title: InvalidLocalVersion status: suspect
import SeveritySuspect from "@partials/severity/suspect-default.mdx";
When this happens
- ✓ Instance is in a Highest Semver or Lowest Semver version group
- ! Local Instance has no version property
- ! Not an error on its own unless an instance of it mismatches
Severity
Site Src Content Docs Status Is Banned (`site/src/content/docs/status/is-banned.mdx`)
title: IsBanned status: fixable
import SeverityTable from "@partials/severity/table-fixable.mdx";
When this happens
- ✘ Instance is in a Banned version group
Severity
Site Src Content Docs Status Is Catalog Definition (`site/src/content/docs/status/is-catalog-definition.mdx`)
title: IsCatalogDefinition status: valid
When this happens
- ✓ Instance is a catalog definition in
pnpm-workspace.yamlor rootpackage.json - ✓ Zero or more siblings use the
catalog:protocol for this dependency
Site Src Content Docs Status Is Catalog (`site/src/content/docs/status/is-catalog.mdx`)
title: IsCatalog status: valid
When this happens
- ✓ Instance is in a Catalog, Highest Semver, or Lowest Semver version group
- ✓ Instance uses the
catalog:protocol and wins out
Site Src Content Docs Status Is Highest Or Lowest Semver (`site/src/content/docs/status/is-highest-or-lowest-semver.mdx`)
title: IsHighestOrLowestSemver status: valid
When this happens
- ✓ Instance is in a Highest Semver or Lowest Semver version group
- ✓ Instance is identical to highest/lowest semver in its group
- ✓ Instance matches its With Range semver group
Site Src Content Docs Status Is Identical To Local (`site/src/content/docs/status/is-identical-to-local.mdx`)
title: IsIdenticalToLocal status: valid
When this happens
- ✓ Instance is in a Highest Semver or Lowest Semver version group
- ✓ Instance is identical to the version of its Local Instance
- ✓ Instance matches its With Range semver group
Site Src Content Docs Status Is Identical To Pin (`site/src/content/docs/status/is-identical-to-pin.mdx`)
title: IsIdenticalToPin status: valid
When this happens
- ✓ Instance is in a Pinned version group
- ✓ Instance is identical to its pinned version group
- ✓ Instance matches its With Range semver group
Site Src Content Docs Status Is Identical To Snap Target (`site/src/content/docs/status/is-identical-to-snap-target.mdx`)
title: IsIdenticalToSnapTarget status: valid
When this happens
- ✓ Instance is in a Snapped To version group
- ✓ Instance is identical to a matching snapTo instance
- ✓ Instance matches its With Range semver group
Site Src Content Docs Status Is Ignored (`site/src/content/docs/status/is-ignored.mdx`)
title: IsIgnored status: valid
When this happens
- ✓ Instance is in an Ignored version group
Site Src Content Docs Status Is Local And Valid (`site/src/content/docs/status/is-local-and-valid.mdx`)
title: IsLocalAndValid status: valid
When this happens
- ✓ Instance is a Local Instance and its version is valid
Site Src Content Docs Status Is Non Semver But Identical (`site/src/content/docs/status/is-non-semver-but-identical.mdx`)
title: IsNonSemverButIdentical status: valid
When this happens
- ✓ Instance is in a Highest Semver or Lowest Semver version group
- ! No Instances have Simple Semver version specifiers
- ✓ Instance is identical to every other instance in its version group
Site Src Content Docs Status Match Conflicts With Highest Or Lowest Semver (`site/src/content/docs/status/match-conflicts-with-highest-or-lowest-semver.mdx`)
title: MatchConflictsWithHighestOrLowestSemver status: conflict
import SeverityUnfixable from "@partials/severity/unfixable.mdx";
When this happens
- ✓ Instance is in a Highest Semver or Lowest Semver version group
- ✓ Instance has same Semver Number as highest/lowest semver in its group
- ✓ Instance matches its With Range semver group
- ✘ Range preferred by semver group will not satisfy the highest/lowest semver
- ? We can't know whether the incompatible range matters or not and have to ask
Severity
Site Src Content Docs Status Match Conflicts With Local (`site/src/content/docs/status/match-conflicts-with-local.mdx`)
title: MatchConflictsWithLocal status: conflict
import SeverityUnfixable from "@partials/severity/unfixable.mdx";
When this happens
- ✓ Instance is in a Highest Semver or Lowest Semver version group
- ✓ Instance has same Semver Number as the Local Instance in its group
- ✓ Instance matches its With Range semver group
- ✘ The Semver Range preferred by its With Range semver group will not satisfy the Local Instance if applied
- ? We can't know whether the incompatible range matters or not and have to ask
Severity
Site Src Content Docs Status Match Conflicts With Snap Target (`site/src/content/docs/status/match-conflicts-with-snap-target.mdx`)
title: MatchConflictsWithSnapTarget status: conflict
import SeverityUnfixable from "@partials/severity/unfixable.mdx";
When this happens
- ✓ Instance is in a Snapped To version group
- ✓ Instance has same Semver Number as the matching snapTo instance
- ✓ Instance matches its With Range semver group
- ✘ Range preferred by semver group will not satisfy the matching snapTo instance
- ? We can't know whether the incompatible range matters or not and have to ask
Severity
Site Src Content Docs Status Matches Semver Group (`site/src/content/docs/status/matches-semver-group.mdx`)
title: MatchesSemverGroup status: valid
When this happens
- ✓ Instance is in a Range Only version group
- ✓ Instance matches its With Range semver group, or no range is enforced
- ! Cross-instance versions are not reconciled in this group
Site Src Content Docs Status Mismatch Conflicts With Highest Or Lowest Semver (`site/src/content/docs/status/mismatch-conflicts-with-highest-or-lowest-semver.mdx`)
title: MismatchConflictsWithHighestOrLowestSemver status: conflict
import SeverityUnfixable from "@partials/severity/unfixable.mdx";
When this happens
- ✓ Instance is in a Highest Semver or Lowest Semver version group
- ✓ Instance has same Semver Number as highest/lowest semver in its group
- ✘ Instance mismatches its With Range semver group
- ✘ The Range preferred by its With Range semver group will not satisfy the highest/lowest semver version if applied
- ? We can't know whether the incompatible range matters or not and have to ask
Severity
Site Src Content Docs Status Mismatch Conflicts With Local (`site/src/content/docs/status/mismatch-conflicts-with-local.mdx`)
title: MismatchConflictsWithLocal status: conflict
import SeverityUnfixable from "@partials/severity/unfixable.mdx";
When this happens
- ✓ Instance is in a Highest Semver or Lowest Semver version group
- ✓ Instance has the same Semver Number as its Local Instance
- ✘ Instance mismatches its With Range semver group
- ✘ Range preferred by its With Range semver group will not satisfy the Local Instance
- ? We can't know whether the incompatible range matters or not and have to ask
Severity
Site Src Content Docs Status Mismatch Conflicts With Snap Target (`site/src/content/docs/status/mismatch-conflicts-with-snap-target.mdx`)
title: MismatchConflictsWithSnapTarget status: conflict
import SeverityUnfixable from "@partials/severity/unfixable.mdx";
When this happens
- ✓ Instance is in a Snapped To version group
- ✓ Instance has same Semver Number as the matching snapTo instance
- ✘ Instance mismatches its With Range semver group
- ✘ Range preferred by semver group will not satisfy the matching snapTo instance
- ? We can't know whether the incompatible range matters or not and have to ask
Severity
Site Src Content Docs Status Missing From Catalog And Non Semver Mismatch (`site/src/content/docs/status/missing-from-catalog-and-non-semver-mismatch.mdx`)
title: MissingFromCatalogAndNonSemverMismatch status: unfixable
import SeverityUnfixable from "@partials/severity/unfixable.mdx";
When this happens
- ✓ Instance is in a Catalog version group
- ✓ MissingFromCatalog applies to multiple instances of the same dependency
- ✘ Their specifiers differ AND at least one is non-semver
- ? Syncpack cannot pick which specifier to enshrine in the catalog
Severity
Site Src Content Docs Status Missing From Catalog (`site/src/content/docs/status/missing-from-catalog.mdx`)
title: MissingFromCatalog status: fixable
import SeverityTable from "@partials/severity/table-fixable.mdx";
When this happens
- ✓ Instance is in a Catalog version group
- ✓ One catalog (or zero, implicit
"default") exists in the project - ✘ Instance's dependency is not defined in any catalog
- ✘ Instance does not use the
catalog:protocol - ! Fix: add dependency to the catalog and replace specifier with
catalog:
The specifier added to the catalog is the unique value when all instances are identical, or the highest semver when all instances are semver.
Severity
Site Src Content Docs Status Non Semver Mismatch (`site/src/content/docs/status/non-semver-mismatch.mdx`)
title: NonSemverMismatch status: fixable
import SeverityUnfixable from "@partials/severity/unfixable.mdx";
When this happens
- ✓ Instance is in a Highest Semver or Lowest Semver version group
- ✘ Instance mismatches others in its group
- ✘ One or more Instances are not Simple Semver
- ? We can't know what's right or what isn't
Severity
Site Src Content Docs Status Not Using Catalog And Catalog Unknown (`site/src/content/docs/status/not-using-catalog-and-catalog-unknown.mdx`)
title: NotUsingCatalogAndCatalogUnknown status: unfixable
import SeverityUnfixable from "@partials/severity/unfixable.mdx";
When this happens
- ✓ Instance is in a Catalog version group
- ✓ Two or more catalogs exist in the project
- ✓ Instance's dependency is defined in zero OR two-or-more of those catalogs
- ✘ Instance does not use the
catalog:protocol - ? Syncpack cannot determine which catalog the dependency belongs to
Severity
Site Src Content Docs Status Not Using Catalog (`site/src/content/docs/status/not-using-catalog.mdx`)
title: NotUsingCatalog status: fixable
import SeverityTable from "@partials/severity/table-fixable.mdx";
When this happens
- ✓ Instance is in a Catalog version group
- ✓ Instance's dependency is defined in exactly one catalog
- ✘ Instance does not use the
catalog:protocol - ! Fix: replace specifier with
catalog:orcatalog:{name}
Severity
Site Src Content Docs Status Pin Overrides Semver Range Mismatch (`site/src/content/docs/status/pin-overrides-semver-range-mismatch.mdx`)
title: PinOverridesSemverRangeMismatch status: fixable
import SeverityTable from "@partials/severity/table-fixable.mdx";
When this happens
- ✓ Instance is in a Pinned version group
- ✓ Instance has same Semver Number as its pinned version group
- ✘ Instance mismatches its With Range semver group
- ! The semver group requires a range which is different to the pinned version
- ! Pinned version wins
Severity
Site Src Content Docs Status Pin Overrides Semver Range (`site/src/content/docs/status/pin-overrides-semver-range.mdx`)
title: PinOverridesSemverRange status: fixable
import SeverityTable from "@partials/severity/table-fixable.mdx";
When this happens
- ✓ Instance is in a Pinned version group
- ✓ Instance has same Semver Number as its pinned version group
- ✓ Instance matches its With Range semver group
- ! The semver group requires a range which is different to the pinned version
- ! Pinned version wins
Severity
Site Src Content Docs Status Refuse To Ban Local (`site/src/content/docs/status/refuse-to-ban-local.mdx`)
title: RefuseToBanLocal status: suspect
import SeveritySuspect from "@partials/severity/suspect-default.mdx";
When this happens
- ✓ Instance is a Local Instance
- ✘ Instance is in a Banned version group
- ✘ Misconfiguration: Syncpack refuses to change the version specifier of a Local Instance
Severity
Site Src Content Docs Status Refuse To Catalog Local (`site/src/content/docs/status/refuse-to-catalog-local.mdx`)
title: RefuseToCatalogLocal status: suspect
import SeveritySuspect from "@partials/severity/suspect-default.mdx";
When this happens
- ✓ Instance is in a Catalog version group
- ✓ Instance is a Local Instance (its own
package.json/versionproperty) - ✘ Local instances cannot use the
catalog:protocol - ! Reconfigure version groups to exclude local instances from the catalog group
Severity
Site Src Content Docs Status Refuse To Pin Local (`site/src/content/docs/status/refuse-to-pin-local.mdx`)
title: RefuseToPinLocal status: suspect
import SeverityTable from "@partials/severity/table-refuse-local.mdx";
When this happens
- ✓ Instance is in a Pinned version group
- ✘ Local Instance mismatches its pinned version group
- ✘ Misconfiguration: Syncpack refuses to change the version specifier of a Local Instance
Severity
Site Src Content Docs Status Refuse To Snap Local (`site/src/content/docs/status/refuse-to-snap-local.mdx`)
title: RefuseToSnapLocal status: suspect
import SeverityTable from "@partials/severity/table-refuse-local.mdx";
When this happens
- ✘ Local Instance is in a Snapped To version group
- ✘ An Instance of this dependency was found in the snapped to package
- ✘ Misconfiguration: Syncpack refuses to change the version specifier of a Local Instance
Severity
Configurable via severity on a Snapped To version group.
Site Src Content Docs Status Same Minor Has Major Mismatch (`site/src/content/docs/status/same-minor-has-major-mismatch.mdx`)
title: SameMinorHasMajorMismatch status: unfixable
import SeverityUnfixable from "@partials/severity/unfixable.mdx";
When this happens
- ✘ Instance is in a Same Minor version group
- ✘ One or more other instances have a different MAJOR version
- ? Crossing a major version boundary is unsafe
- ? We cannot know which MAJOR version the user wants and have to ask them
Severity
Site Src Content Docs Status Same Minor Mismatch (`site/src/content/docs/status/same-minor-mismatch.mdx`)
title: SameMinorMismatch status: fixable
import SeverityUnfixable from "@partials/severity/unfixable.mdx";
When this happens
- ✘ Instance mismatches its Same Minor version group
- ? Instance does not belong to a With Range semver group
- ? We can't know what range the user wants and have to ask them
Severity
Site Src Content Docs Status Same Minor Overrides Semver Range Mismatch (`site/src/content/docs/status/same-minor-overrides-semver-range-mismatch.mdx`)
title: SameMinorOverridesSemverRangeMismatch status: fixable
import SeverityTable from "@partials/severity/table-fixable.mdx";
When this happens
- ✓ Instance has same major.minor as all other instances in its group
- ✘ Instance mismatches its With Range semver group
- ! The semver group requires a range which would break Same Minor policy
- ! Same minor policy wins
Severity
Configurable via severity on a Same Minor version group.
Site Src Content Docs Status Same Minor Overrides Semver Range (`site/src/content/docs/status/same-minor-overrides-semver-range.mdx`)
title: SameMinorOverridesSemverRange status: fixable
import SeverityTable from "@partials/severity/table-fixable.mdx";
When this happens
- ✓ Instance has same major.minor as all other instances in its group
- ✓ Instance matches its With Range semver group
- ! The semver group requires a range which would break Same Minor policy
- ! Same minor policy wins
Severity
Configurable via severity on a Same Minor version group.
Site Src Content Docs Status Same Range Mismatch (`site/src/content/docs/status/same-range-mismatch.mdx`)
title: SameRangeMismatch status: fixable
import SeverityUnfixable from "@partials/severity/unfixable.mdx";
When this happens
- ✓ Instance is in a Highest Semver or Lowest Semver version group
- ✘ Instance mismatches its Same Range version group
- ? Instance does not belong to a With Range semver group
- ? We can't know what range the user wants and have to ask them
Severity
Site Src Content Docs Status Satisfies Highest Or Lowest Semver (`site/src/content/docs/status/satisfies-highest-or-lowest-semver.mdx`)
title: SatisfiesHighestOrLowestSemver status: valid
When this happens
- ✓ Instance is in a Highest Semver or Lowest Semver version group
- ✓ Instance has same Semver Number as highest/lowest semver in its group
- ✓ Instance matches its With Range semver group
- ✓ Range preferred by semver group satisfies the highest/lowest semver
- ! Considered a loose match we should highlight
Site Src Content Docs Status Satisfies Local (`site/src/content/docs/status/satisfies-local.mdx`)
title: SatisfiesLocal status: valid
When this happens
- ✓ Instance is in a Highest Semver or Lowest Semver version group
- ✓ Instance matches the version of its Local Instance
- ✓ Instance matches its With Range semver group
- ! Considered a loose match we should highlight
Site Src Content Docs Status Satisfies Same Minor Group (`site/src/content/docs/status/satisfies-same-minor-group.mdx`)
title: SatisfiesSameMinorGroup status: valid
When this happens
- ✓ Instance matches its Same Minor version group
- ✓ Instance matches its With Range semver group
Site Src Content Docs Status Satisfies Same Range Group (`site/src/content/docs/status/satisfies-same-range-group.mdx`)
title: SatisfiesSameRangeGroup status: valid
When this happens
- ✓ Instance matches its Same Range version group
- ✓ Instance matches its With Range semver group
Site Src Content Docs Status Satisfies Snap Target (`site/src/content/docs/status/satisfies-snap-target.mdx`)
title: SatisfiesSnapTarget status: valid
When this happens
- ✓ Instance is in a Snapped To version group
- ✓ Instance has same Semver Number as matching snapTo instance
- ✓ Instance matches its With Range semver group
- ✓ Range preferred by semver group satisfies the matching snapTo instance
- ! Considered a loose match we should highlight
Site Src Content Docs Status Semver Range Mismatch (`site/src/content/docs/status/semver-range-mismatch.mdx`)
title: SemverRangeMismatch status: fixable
import SeverityTable from "@partials/severity/table-fixable.mdx";
When this happens
- ✓ Instance is in a Highest Semver or Lowest Semver version group
- ✓ Instance has same Semver Number as highest/lowest semver in its group
- ✘ Instance mismatches its With Range semver group
- ✓ Range preferred by semver group satisfies the highest/lowest semver
- ✓ Fixing the semver range satisfy both groups
Severity
Configurable via severity on any of the following version groups: Highest Semver, Lowest Semver, Same Range, Same Minor, Range Only, Snapped To.
Site Src Content Docs Update Groups Ignored (`site/src/content/docs/update-groups/ignored.mdx`)
title: Ignored
import { Badge } from "@astrojs/starlight/components";
import Packages from "@partials/group-config/packages.mdx";
import Dependencies from "@partials/group-config/dependencies.mdx";
import DependencyTypes from "@partials/group-config/dependency-types.mdx";
import SpecifierTypes from "@partials/group-config/specifier-types.mdx";
import Label from "@partials/group-config/label.mdx";
Skip these dependencies entirely when looking for registry updates. Matched instances are reported as valid and are not offered as candidates by the update command, even when newer versions exist on the npm registry.
A common use is opting peer dependencies out of updates, since the consuming project (not the publisher) owns the peer range.
Configuration
isIgnored
This property activates this behaviour for a given Update Group.
{
"updateGroups": [
{
"dependencyTypes": ["peer"],
"isIgnored": true
}
]
}dependencies
dependencyTypes
specifierTypes
label
packages
Site Src Content Docs Update Groups Targeted (`site/src/content/docs/update-groups/targeted.mdx`)
title: Targeted
import { Badge } from "@astrojs/starlight/components";
import Packages from "@partials/group-config/packages.mdx";
import Dependencies from "@partials/group-config/dependencies.mdx";
import DependencyTypes from "@partials/group-config/dependency-types.mdx";
import SpecifierTypes from "@partials/group-config/specifier-types.mdx";
import Label from "@partials/group-config/label.mdx";
Clamp the highest registry update offered for matched instances. The CLI's --target value still applies (the stricter of the two wins), so a group with target: "latest" cannot loosen a CLI run that used --target patch.
Configuration
target
One of "patch", "minor", or "latest".
{
"updateGroups": [
{
"dependencies": ["storybook", "@storybook/**"],
"target": "patch"
},
{
"dependencyTypes": ["dev"],
"target": "minor"
}
]
}| Value | Allowed update relative to current version |
|---|---|
patch |
Same major and minor; higher patch only. |
minor |
Same major; higher minor or patch. |
latest |
Any newer version, including major bumps. |
dependencies
dependencyTypes
specifierTypes
label
packages
Site Src Content Docs Version Groups Banned (`site/src/content/docs/version-groups/banned.mdx`)
title: Banned
import Dependencies from "@partials/group-config/dependencies.mdx";
import DependencyTypes from "@partials/group-config/dependency-types.mdx";
import SpecifierTypes from "@partials/group-config/specifier-types.mdx";
import Label from "@partials/group-config/label.mdx";
import Packages from "@partials/group-config/packages.mdx";
import SeverityGroupSection from "@partials/severity/group-section.mdx";
import { Badge } from "@astrojs/starlight/components";
import Details from "@site/components/details.astro";
Prevent dependencies from being used anywhere in your monorepo, or only in specific packages. Common cases are blocking legacy packages, conflicting libraries, or packages that violate your security or licensing policy. When syncpack finds a banned dependency, it flags it as an issue that must be removed.
Configuration
isBanned
This property activates this behaviour for a given Version Group.
{
"versionGroups": [
{
"dependencies": ["never-gonna"],
"isBanned": true
}
]
}dependencies
dependencyTypes
specifierTypes
label
packages
severity
{
"versionGroups": [
{
"dependencies": ["never-gonna"],
"isBanned": true,
"severity": {
"IsBanned": "error"
}
}
]
}Status Codes
These are all the issues that a {frontmatter.title} Version Group can find:
Fixable
Suspect
Site Src Content Docs Version Groups Catalog (`site/src/content/docs/version-groups/catalog.mdx`)
title: Catalog sidebar: badge: New
import { Badge } from "@astrojs/starlight/components";
import Packages from "@partials/group-config/packages.mdx";
import Dependencies from "@partials/group-config/dependencies.mdx";
import DependencyTypes from "@partials/group-config/dependency-types.mdx";
import SpecifierTypes from "@partials/group-config/specifier-types.mdx";
import Label from "@partials/group-config/label.mdx";
import SeverityGroupSection from "@partials/severity/group-section.mdx";
Require dependencies to be defined in a pnpm or Bun catalog and consumed via the catalog: protocol. Catalog definitions live in pnpm-workspace.yaml (pnpm) or the root package.json at /catalog, /catalogs/{name}, /workspaces/catalog, or /workspaces/catalogs/{name} (Bun).
Use this group when you want a single source of truth for a dependency's version across the monorepo. Members of the group must either be a catalog definition or use catalog: / catalog:{name} to point at one. Syncpack will fix instances that use a literal version specifier by replacing them with catalog: and, where needed, inserting the dependency into the catalog.
When no catalog yet exists and the project uses pnpm or Bun, Syncpack creates the implicit default catalog at fix time. For npm, yarn, or unknown package managers there is no catalog system to write to and instances are flagged as CannotInferCatalogFile.
Configuration
policy
Set the policy to "catalog" to enable this behaviour for a Version Group.
{
"versionGroups": [
{
"label": "All production deps must come from the catalog",
"dependencyTypes": ["prod"],
"policy": "catalog"
}
]
}dependencies
dependencyTypes
specifierTypes
label
packages
severity
{
"versionGroups": [
{
"label": "All production deps must come from the catalog",
"dependencyTypes": ["prod"],
"policy": "catalog",
"severity": {
"NotUsingCatalog": "error",
"MissingFromCatalog": "warn"
}
}
]
}Status Codes
These are all the issues that a {frontmatter.title} Version Group can find:
Valid
Fixable
Unfixable
Suspect
Site Src Content Docs Version Groups Highest Semver (`site/src/content/docs/version-groups/highest-semver.mdx`)
title: Highest Semver
import { Badge } from "@astrojs/starlight/components";
import Packages from "@partials/group-config/packages.mdx";
import Dependencies from "@partials/group-config/dependencies.mdx";
import DependencyTypes from "@partials/group-config/dependency-types.mdx";
import SpecifierTypes from "@partials/group-config/specifier-types.mdx";
import Label from "@partials/group-config/label.mdx";
import SeverityGroupSection from "@partials/severity/group-section.mdx";
Require all dependencies in this group to use the highest semver version found of all the instances where it is already installed in your monorepo. When versions differ, syncpack will align them to the highest one installed.
Configuration
dependencies
dependencyTypes
specifierTypes
label
packages
severity
{
"versionGroups": [
{
"dependencies": ["legacy-pkg"],
"severity": {
"DiffersToHighestOrLowestSemver": "warn"
}
}
]
}DiffersToNpmRegistry is not configurable via severity. Registry-update behaviour is controlled by updateGroups.
Status Codes
These are all the issues that a {frontmatter.title} Version Group can find:
Valid
Fixable
Conflict
Site Src Content Docs Version Groups Ignored (`site/src/content/docs/version-groups/ignored.mdx`)
title: Ignored
import { Badge } from "@astrojs/starlight/components";
import Packages from "@partials/group-config/packages.mdx";
import Dependencies from "@partials/group-config/dependencies.mdx";
import DependencyTypes from "@partials/group-config/dependency-types.mdx";
import SpecifierTypes from "@partials/group-config/specifier-types.mdx";
import Label from "@partials/group-config/label.mdx";
import Details from "@site/components/details.astro";
Have syncpack ignore these dependencies completely.
Defining version groups for dependencies you know you can easily fix, followed by a catch-all Ignored Version Group as the last member of your versionGroups array is a good way to incrementally adopt syncpack.
Configuration
isIgnored
This property activates this behaviour for a given Version Group.
{
"versionGroups": [
{
"dependencies": ["keep-walking"],
"isIgnored": true
}
]
}dependencies
dependencyTypes
specifierTypes
label
packages
severity
An Ignored group emits no statuses to tune. A severity map written here is accepted and silently discarded. Set isIgnored to false and pick a different group type if you want to control how issues are reported.
Status Codes
These are all the issues that a {frontmatter.title} Version Group can find:
Valid
Site Src Content Docs Version Groups Lowest Semver (`site/src/content/docs/version-groups/lowest-semver.mdx`)
title: Lowest Semver
import { Badge } from "@astrojs/starlight/components";
import Packages from "@partials/group-config/packages.mdx";
import Dependencies from "@partials/group-config/dependencies.mdx";
import DependencyTypes from "@partials/group-config/dependency-types.mdx";
import SpecifierTypes from "@partials/group-config/specifier-types.mdx";
import Label from "@partials/group-config/label.mdx";
import SeverityGroupSection from "@partials/severity/group-section.mdx";
Require all dependencies in this group to use the lowest semver version found of all the instances where it is already installed in your monorepo. When versions differ, syncpack will align them to the lowest one installed.
Examples
{
"versionGroups": [
{
"dependencies": ["swing", "low"],
"preferVersion": "lowestSemver"
}
]
}Configuration
preferVersion
Must be set to lowestSemver.
dependencies
dependencyTypes
specifierTypes
label
packages
severity
{
"versionGroups": [
{
"dependencies": ["swing", "low"],
"preferVersion": "lowestSemver",
"severity": {
"DiffersToHighestOrLowestSemver": "warn"
}
}
]
}DiffersToNpmRegistry is not configurable via severity. Registry-update behaviour is controlled by updateGroups.
Status Codes
These are all the issues that a {frontmatter.title} Version Group can find:
Valid
Fixable
Conflict
Site Src Content Docs Version Groups Pinned (`site/src/content/docs/version-groups/pinned.mdx`)
title: Pinned
import { Badge } from "@astrojs/starlight/components";
import Packages from "@partials/group-config/packages.mdx";
import Dependencies from "@partials/group-config/dependencies.mdx";
import DependencyTypes from "@partials/group-config/dependency-types.mdx";
import SpecifierTypes from "@partials/group-config/specifier-types.mdx";
import Label from "@partials/group-config/label.mdx";
import SeverityGroupSection from "@partials/severity/group-section.mdx";
import Details from "@site/components/details.astro";
Pin the version of all dependencies in this group to match a specific version you've defined.
Configuration
pinVersion
The version specifier you would like to use, this can be anything supported by a package manager.
{
"versionGroups": [
{
"dependencies": ["@types/node"],
"pinVersion": "18.14.2"
}
]
}dependencies
dependencyTypes
specifierTypes
label
packages
severity
{
"versionGroups": [
{
"dependencies": ["@types/node"],
"pinVersion": "18.14.2",
"severity": {
"DiffersToPin": "error",
"RefuseToPinLocal": "fix"
}
}
]
}Status Codes
These are all the issues that a {frontmatter.title} Version Group can find:
Valid
Fixable
Suspect
Site Src Content Docs Version Groups Range Only (`site/src/content/docs/version-groups/range-only.mdx`)
title: Range Only sidebar: badge: New
import { Badge } from "@astrojs/starlight/components";
import Packages from "@partials/group-config/packages.mdx";
import Dependencies from "@partials/group-config/dependencies.mdx";
import DependencyTypes from "@partials/group-config/dependency-types.mdx";
import SpecifierTypes from "@partials/group-config/specifier-types.mdx";
import Label from "@partials/group-config/label.mdx";
import SeverityGroupSection from "@partials/severity/group-section.mdx";
Loosens syncpack to only enforce that every dependency uses the semver range prefix required by its semver group — ^, ~, exact, etc. and ignores the version number. This is useful when you want to standardise how packages pin their dependencies, but are otherwise not ready or don't want to enforce a specific version they all should use.
:::note
This is not sameRange. sameRange checks that every range overlaps on at least one shared version. semverRangeOnly only checks the prefix.
:::
When the update command runs, the new version is taken from the registry and the prefix from the semver group is applied to it.
Examples
In this example we are only ensuring that semver ranges are used consistently. dependencies should use exact versions and devDependencies should use ~, the specific versions are left unchanged.
{
"semverGroups": [
{
"label": "Use exact versions for dependencies",
"dependencyTypes": ["prod"],
"range": ""
},
{
"label": "Use ~ for devDependencies",
"dependencyTypes": ["dev"],
"range": "~"
}
],
"versionGroups": [
{
"label": "Only enforce semver ranges, leave versions unchanged",
"policy": "semverRangeOnly"
}
]
}Configuration
policy
Choose the "semverRangeOnly" policy to apply this behaviour to a Version Group.
{
"versionGroups": [
{
"dependencies": ["react"],
"policy": "semverRangeOnly"
}
]
}dependencies
dependencyTypes
specifierTypes
label
packages
severity
{
"versionGroups": [
{
"dependencies": ["react"],
"policy": "semverRangeOnly",
"severity": {
"SemverRangeMismatch": "warn"
}
}
]
}Status Codes
These are all the issues that a {frontmatter.title} Version Group can find:
Valid
Fixable
Site Src Content Docs Version Groups Same Minor (`site/src/content/docs/version-groups/same-minor.mdx`)
title: Same Minor
import { Badge } from "@astrojs/starlight/components";
import Packages from "@partials/group-config/packages.mdx";
import Dependencies from "@partials/group-config/dependencies.mdx";
import DependencyTypes from "@partials/group-config/dependency-types.mdx";
import SpecifierTypes from "@partials/group-config/specifier-types.mdx";
import Label from "@partials/group-config/label.mdx";
import SeverityGroupSection from "@partials/severity/group-section.mdx";
import Details from "@site/components/details.astro";
Loosen requirements to only ensure that the MAJOR.MINOR.x version number should match for all members of this group, allowing different patch versions. The only semver ranges allowed are exact and ~ as others will allow versions to be installed outside of this range.
Consider whether you need this behaviour because it will result in another copy of the same dependency being installed for every patch version number which is not the same. Usually we're trying to reduce the number of variables in our system and increase confidence, so most people won't need this.
One use case where a Same Minor group can help is when using a dependency group to alias multiple related packages such as @aws-sdk/** into one, each package in the set may not have identical version numbers, but they should fall within the same minor.
Configuration
policy
Set the policy to "sameMinor" to enable this behaviour for a Version Group.
{
"versionGroups": [
{
"dependencies": ["react", "react-dom"],
"policy": "sameMinor"
}
]
}dependencies
dependencyTypes
specifierTypes
label
preferVersion
When set, determines how to resolve versions when instances differ in their MAJOR.MINOR (while sharing the same MAJOR version).
{
"versionGroups": [
{
"dependencies": ["react", "react-dom"],
"policy": "sameMinor",
"preferVersion": "highestSemver"
}
]
}Possible values
The default status for instances that differ in MAJOR.MINOR is SameMinorMismatch, which is not auto-fixable, since syncpack can't know which minor versions are safe to change without your guidance.
:::caution
Setting a preferVersion loosens this requirement, but beware of dependencies which are still within 0.x.x or whose authors don't follow strict semver correctly.
:::
"highestSemver"- Updates instances to use the highest MAJOR.MINOR version found in the group"lowestSemver"- Updates instances to use the lowest MAJOR.MINOR version found in the group
packages
severity
{
"versionGroups": [
{
"dependencies": ["react", "react-dom"],
"policy": "sameMinor",
"preferVersion": "highestSemver",
"severity": {
"DiffersToHighestOrLowestSemverMinor": "error"
}
}
]
}SameMinorMismatch, SameMinorHasMajorMismatch, and NonSemverMismatch are unfixable. They are always reported as errors and cannot be tuned via severity.
Status Codes
These are all the issues that a {frontmatter.title} Version Group can find:
Valid
Fixable
- DiffersToHighestOrLowestSemverMinor
- SameMinorOverridesSemverRange
- SameMinorOverridesSemverRangeMismatch
- SemverRangeMismatch
Unfixable
Site Src Content Docs Version Groups Same Range (`site/src/content/docs/version-groups/same-range.mdx`)
title: Same Range
import { Badge } from "@astrojs/starlight/components";
import Packages from "@partials/group-config/packages.mdx";
import Dependencies from "@partials/group-config/dependencies.mdx";
import DependencyTypes from "@partials/group-config/dependency-types.mdx";
import SpecifierTypes from "@partials/group-config/specifier-types.mdx";
import Label from "@partials/group-config/label.mdx";
import SeverityGroupSection from "@partials/severity/group-section.mdx";
import Details from "@site/components/details.astro";
Checks that every instance of a dependency uses a semver range that overlaps with every other instance in the group. Ranges don't need to be identical, they just need to share at least one version in common (ie. they intersect).
This is the loosest version group policy. It does not enforce identical versions; the default Highest Semver group does that. It does not enforce same minor versions; use sameMinor for that.
:::cautionsameRange only works with semver ranges like ^1.2.3, >=1.0.0, or ~2.0.0. Exact pinned versions like 1.0.0 and 1.0.1 are non-overlapping ranges. They will be flagged as mismatches because no single version satisfies both. If you want to enforce that exact versions share the same minor number, use sameMinor instead.
:::
When to use this
- Peer dependencies where different packages legitimately need different ranges, as long as a compatible version can be resolved
- Typed dependencies (
fooand@types/foo) that may move on different release cadences but must coexist
Examples
Overlapping ranges, at least one version satisfies both:
>=1.0.0and<=2.0.0✅ (versions 1.0.0 to 2.0.0 satisfy both)>=1.0.0and^1.2.3✅ (versions 1.2.3 to 1.x.x satisfy both)^1.0.0and~1.4.2✅ (versions 1.4.2 to 1.4.x satisfy both)
Non-overlapping ranges, no version exists in both:
>=1.0.0and<1.0.0✗~1.0.0and1.4.2✗ (~1.0.0covers 1.0.x, the exact version 1.4.2 is outside it)
Mismatches in a Same Range group are unfixable. Syncpack cannot auto-fix them because it doesn't know which range should change. You'll need to resolve these manually.
Configuration
policy
Choose the "sameRange" policy to apply this behaviour to a Version Group.
{
"versionGroups": [
{
"dependencies": ["eslint"],
"policy": "sameRange"
}
]
}dependencies
dependencyTypes
specifierTypes
label
packages
severity
{
"versionGroups": [
{
"dependencies": ["eslint"],
"policy": "sameRange",
"severity": {
"SemverRangeMismatch": "warn"
}
}
]
}SameRangeMismatch is unfixable. It is always reported as an error and cannot be tuned via severity.
Status Codes
These are all the issues that a {frontmatter.title} Version Group can find:
Valid
Fixable
Unfixable
Site Src Content Docs Version Groups Snapped To (`site/src/content/docs/version-groups/snapped-to.mdx`)
title: Snapped To
import { Badge } from "@astrojs/starlight/components";
import Packages from "@partials/group-config/packages.mdx";
import Dependencies from "@partials/group-config/dependencies.mdx";
import DependencyTypes from "@partials/group-config/dependency-types.mdx";
import SpecifierTypes from "@partials/group-config/specifier-types.mdx";
import Label from "@partials/group-config/label.mdx";
import SeverityGroupSection from "@partials/severity/group-section.mdx";
import Details from "@site/components/details.astro";
Synchronise versions by following a source package. Every dependency in this group will use the same version as defined in the packages you've designated via the snapTo array.
This is useful when certain packages within your monorepo are the source of truth for dependency versions. For example, if your main application package has been carefully tested with specific versions, you want all other packages to follow those same versions to ensure consistency and reduce the variables in your system.
Configuration
snapTo
- The values refer to the
nameproperty of the package.json files developed in your monorepo. - Multiple values can be added to provide fallback packages to try in the event that the dependency is not present in the earlier packages in the array.
{
"versionGroups": [
{
"dependencies": ["react", "react-native"],
"snapTo": ["mobile-app"]
}
]
}dependencies
dependencyTypes
specifierTypes
label
packages
severity
{
"versionGroups": [
{
"dependencies": ["react", "react-native"],
"snapTo": ["mobile-app"],
"severity": {
"DiffersToSnapTarget": "error",
"RefuseToSnapLocal": "fix"
}
}
]
}Status Codes
These are all the issues that a {frontmatter.title} Version Group can find:
Valid
Fixable
Suspect
Conflict
--- METRICS ---
- Files Extracted: 106
- Estimated Token Budget: ~44830 tokens
- Canonical Reference: https://codewiki.google/github.com/JamieMason/syncpack