syncpack Documentation

Consistent dependency versions in large JavaScript Monorepos.

2,109 stars Rust Rust 106 files · ~44,912 tokens #bun#catalogs#dependencies#linter#monorepo#npm#nx#pnpm
RAW Doc

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

bash
npm install --save-dev syncpack

Guides

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

bash
# 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

bash
# 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

bash
# 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

bash
# 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

bash
# 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

bash
# 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 -h

Badges


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.

bash frame="none"
npx syncpack list --dependency-types prod

Run 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

bash frame="none"
npx syncpack update -h

or display documentation and examples with --help

bash frame="none"
npx syncpack update --help

Install

When setting up a project for real, install syncpack in devDependencies so that everyone working on your project uses the same version.

bash frame="none"
npm install syncpack --save-dev

The locally installed binary can be run using npm exec

bash frame="none"
npm exec syncpack -- list

Introduction

:::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.

bash frame="none"
syncpack list --dependency-types prod --sort count

Some 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.

bash frame="none"
syncpack lint --dependency-types prod

If the suggested changes look ok, we can autofix them.

bash frame="none"
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.

bash frame="none"
syncpack fix --dependency-types prod --dependencies react

All of syncpack's commands can be filtered in the same way, let's see if react needs updating.

bash frame="none"
syncpack update --check --dependencies react

Or list every dependency with eslint somewhere in the name.

bash frame="none"
syncpack list --dependencies '**eslint**'

Or every dependency published under the @types scope.

bash frame="none"
syncpack list --dependencies '@types/**'

We can find every dependency installed with an exact version number.

bash frame="none"
syncpack list --specifier-types exact

Or look for updates to devDependencies where only the patch version is newer than what we have installed.

bash frame="none"
syncpack update --check --dependency-types dev --target patch

And by removing the --check option we can write the newer versions to our files.

bash frame="none"
syncpack update --dependencies react

Each command supports --help for examples and available options.

bash frame="none"
syncpack list --help

Configuration

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.

json title=".syncpackrc.json"
{
  "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:

json title=".syncpackrc.json"
{
  "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.

json title=".syncpackrc.json"
{
  "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

  1. Read the Peer Dependencies guide if your projects uses them, it will be important to understand them from a version consistency point of view.
  2. Semver Groups configuration lets you ensure for example that version numbers in devDependencies always use ^ while dependencies always use ~.
  3. With Version Groups configuration 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.

{pages.map((page) => ( ))}

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.

{pages.map((page) => ( ))}

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.

{pages.map((page) => ( ))}

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.

{pages.map((page) => ( ))}

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:

json title=".syncpackrc.json"
{
  "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:

json title=".syncpackrc.json"
{
  "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:

json title=".syncpackrc.json"
{
  "semverGroups": [
    {
      "dependencies": ["@foo/**"],
      "range": "~"
    }
  ]
}

4: Production dependencies should have fixed version numbers, but development and peer dependencies can be broader.

json title=".syncpackrc.json"
{
  "semverGroups": [
    {
      "dependencyTypes": [
        "prod",
        "resolutions",
        "overrides",
        "pnpmOverrides",
        "local"
      ],
      "range": ""
    },
    {
      "dependencyTypes": ["dev"],
      "range": "~"
    },
    {
      "dependencyTypes": ["peer"],
      "range": "^"
    }
  ]
}

Variants

{pages.map((page) => ( ))}

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

jsonc title=".syncpackrc.json"
{
  "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.

json
{
  "updateGroups": [
    {
      "target": "patch"
    }
  ]
}
json
{
  "updateGroups": [
    {
      "dependencies": ["**"],
      "dependencyTypes": ["**"],
      "packages": ["**"],
      "specifierTypes": ["**"],
      "target": "patch"
    }
  ]
}

Variants

{pages.map((page) => ( ))}

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.

json title=".syncpackrc.json"
{
  "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.

json
{
  "versionGroups": [
    {
      "label": "Ignore everything",
      "isIgnored": true
    }
  ]
}
json
{
  "versionGroups": [
    {
      "label": "Ignore everything",
      "dependencies": ["**"],
      "dependencyTypes": ["**"],
      "packages": ["**"],
      "specifierTypes": ["**"],
      "isIgnored": true
    }
  ]
}

Variants

{pages.map((page) => ( ))}

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

bash frame="none"
# 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 -h

Options

--config " />

--dependencies " />

--dependency-types " />

--dry-run

--log-levels " />

--no-ansi

--reporter " />

--show " />

--sort " />

--source " />

--source-mode " />

--specifier-types " />

--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

bash frame="none"
# 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

Options

--check

--config " />

--dry-run

--log-levels " />

--no-ansi

--reporter " />

--source " />

--source-mode " />

--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

bash frame="none"
# 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 -h

TypeScript

Each instance printed by syncpack json has the type JsonOutput

Options

--config " />

--dependencies " />

--dependency-types " />

--log-levels " />

--no-ansi

--sort " />

--source " />

--source-mode " />

--specifier-types " />

--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

bash frame="none"
# 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

Options

--config " />

--dependencies " />

--dependency-types " />

--log-levels " />

--no-ansi

--show " />

--sort " />

--source " />

--source-mode " />

--specifier-types " />

--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

bash frame="none"
# 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

Options

--config " />

--dependencies " />

--dependency-types " />

--log-levels " />

--no-ansi

--show " />

--sort " />

--source " />

--source-mode " />

--specifier-types " />

--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

bash frame="none"
# 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

Options

--check

--config " />

--dependencies " />

--dependency-types " />

--dry-run

--interactive

--log-levels " />

--no-ansi

--no-cache

--source " />

--source-mode " />

--specifier-types " />

--target " />

--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:

This is how the default dependency types are defined:

json title=".syncpackrc.json"
{
  "$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 @.

json title="package.json"
{
  "packageManager": "[email protected]"
}
json title=".syncpackrc.json"
{
  "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:

  1. --dependency-types
  2. versionGroup.dependencyTypes
  3. semverGroup.dependencyTypes
  4. dependencyGroup.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.

json title="package.json"
{
  "devEngines": {
    "runtime": {
      "name": "node",
      "version": "22.11.0"
    }
  }
}
json title=".syncpackrc.json"
{
  "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:

  1. --dependency-types
  2. versionGroup.dependencyTypes
  3. semverGroup.dependencyTypes
  4. dependencyGroup.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.

json title="package.json"
{
  "engines": {
    "node": "22.11.0"
  }
}
json title=".syncpackrc.json"
{
  "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:

  1. --dependency-types
  2. versionGroup.dependencyTypes
  3. semverGroup.dependencyTypes
  4. dependencyGroup.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.

json title="package.json"
{
  "dependencies": {
    "pnpm": "10.10.0",
    "prettier": "3.5.3"
  }
}
json title=".syncpackrc.json"
{
  "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:

  1. --dependency-types
  2. versionGroup.dependencyTypes
  3. semverGroup.dependencyTypes
  4. dependencyGroup.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.

jsonc title=".syncpackrc.json"
{
  "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