Nerds Produce Money

    syncpack

    8.4.11 • Public • Published

    syncpack

    Manage multiple package.json files, such as in Lerna Monorepos and Yarn/Pnpm Workspaces

    NPM version NPM downloads Build Status Maintainability

    🌩 Installation

    npm install --global syncpack

    🤖 GitHub Action

    As of May 2022 there is now a Syncpack GitHub Action. It is new and less stable than syncpack itself, but please give it a try and give your feedback.

    📝 Commands

    fix-mismatches

    Ensure that multiple packages requiring the same dependency define the same version, so that every package requires eg. react@16.4.2, instead of a combination of react@16.4.2, react@0.15.9, and react@16.0.0.

    See versionGroups if you have advanced requirements.

    Options
    -s, --source [pattern]  glob pattern for package.json files to read from
    -f, --filter [pattern]  only include dependencies whose name matches this regex
    -p, --prod              include dependencies
    -d, --dev               include devDependencies
    -P, --peer              include peerDependencies
    -R, --resolutions       include resolutions (yarn)
    -o, --overrides         include overrides (npm)
    -O, --pnpmOverrides     include overrides (pnpm)
    -w, --workspace         include locally developed package versions
    -i, --indent [value]    override indentation. defaults to "  "
    -c, --config <path>     path to a syncpack config file
    -h, --help              display help for command
    
    Examples
    # uses defaults for resolving packages
    syncpack fix-mismatches
    # uses packages defined by --source when provided
    syncpack fix-mismatches --source "apps/*/package.json"
    # multiple globs can be provided like this
    syncpack fix-mismatches --source "apps/*/package.json" --source "core/*/package.json"
    # uses dependencies regular expression defined by --filter when provided
    syncpack fix-mismatches --filter "typescript|tslint"
    # only inspect "devDependencies"
    syncpack fix-mismatches --dev
    # only inspect "devDependencies" and "peerDependencies"
    syncpack fix-mismatches --dev --peer
    # indent package.json with 4 spaces instead of 2
    syncpack fix-mismatches --indent "    "

    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.

    Options
    -s, --source [pattern]  glob pattern for package.json files to read from
    -i, --indent [value]    override indentation. defaults to "  "
    -c, --config <path>     path to a syncpack config file
    -h, --help              display help for command
    
    Examples
    # uses defaults for resolving packages
    syncpack format
    # uses packages defined by --source when provided
    syncpack format --source "apps/*/package.json"
    # multiple globs can be provided like this
    syncpack format --source "apps/*/package.json" --source "core/*/package.json"
    # indent package.json with 4 spaces instead of 2
    syncpack format --indent "    "

    lint-semver-ranges

    Check whether dependency versions used within "dependencies", "devDependencies", and "peerDependencies" follow a consistent format.

    See semverGroups if you have advanced requirements.

    Options
    -s, --source [pattern]      glob pattern for package.json files to read from
    -p, --prod                  include dependencies
    -d, --dev                   include devDependencies
    -P, --peer                  include peerDependencies
    -R, --resolutions           include resolutions (yarn)
    -o, --overrides             include overrides (npm)
    -O, --pnpmOverrides         include overrides (pnpm)
    -f, --filter [pattern]      only include dependencies whose name matches this regex
    -r, --semver-range <range>  see supported ranges below. defaults to ""
    -c, --config <path>         path to a syncpack config file
    -w, --workspace             include locally developed package versions
    -h, --help                  display help for command
    
    Examples
    # uses defaults for resolving packages
    syncpack lint-semver-ranges
    # uses packages defined by --source when provided
    syncpack lint-semver-ranges --source "apps/*/package.json"
    # multiple globs can be provided like this
    syncpack lint-semver-ranges --source "apps/*/package.json" --source "core/*/package.json"
    # uses dependencies regular expression defined by --filter when provided
    syncpack lint-semver-ranges --filter "typescript|tslint"
    # use ~ range instead of default ""
    syncpack lint-semver-ranges --semver-range ~
    # use ~ range in "devDependencies"
    syncpack lint-semver-ranges --dev --semver-range ~
    # use ~ range in "devDependencies" and "peerDependencies"
    syncpack lint-semver-ranges --dev --peer --semver-range ~

    list

    List all dependencies required by your packages.

    Options
    -s, --source [pattern]  glob pattern for package.json files to read from
    -p, --prod              include dependencies
    -d, --dev               include devDependencies
    -P, --peer              include peerDependencies
    -R, --resolutions       include resolutions (yarn)
    -o, --overrides         include overrides (npm)
    -O, --pnpmOverrides     include overrides (pnpm)
    -f, --filter [pattern]  only include dependencies whose name matches this regex
    -c, --config <path>     path to a syncpack config file
    -w, --workspace         include locally developed package versions
    -h, --help              display help for command
    
    Examples
    # uses defaults for resolving packages
    syncpack list
    # uses packages defined by --source when provided
    syncpack list --source "apps/*/package.json"
    # multiple globs can be provided like this
    syncpack list --source "apps/*/package.json" --source "core/*/package.json"
    # uses dependencies regular expression defined by --filter when provided
    syncpack list --filter "typescript|tslint"
    # only inspect "devDependencies"
    syncpack list --dev
    # only inspect "devDependencies" and "peerDependencies"
    syncpack list --dev --peer

    list-mismatches

    List dependencies which are required by multiple packages, where the version is not the same across every package.

    See versionGroups if you have advanced requirements.

    Options
    -s, --source [pattern]  glob pattern for package.json files to read from
    -p, --prod              include dependencies
    -d, --dev               include devDependencies
    -P, --peer              include peerDependencies
    -R, --resolutions       include resolutions (yarn)
    -o, --overrides         include overrides (npm)
    -O, --pnpmOverrides     include overrides (pnpm)
    -f, --filter [pattern]  only include dependencies whose name matches this regex
    -c, --config <path>     path to a syncpack config file
    -w, --workspace         include locally developed package versions
    -h, --help              display help for command
    
    Examples
    # uses defaults for resolving packages
    syncpack list-mismatches
    # uses packages defined by --source when provided
    syncpack list-mismatches --source "apps/*/package.json"
    # multiple globs can be provided like this
    syncpack list-mismatches --source "apps/*/package.json" --source "core/*/package.json"
    # uses dependencies regular expression defined by --filter when provided
    syncpack list-mismatches --filter "typescript|tslint"
    # only inspect "devDependencies"
    syncpack list-mismatches --dev
    # only inspect "devDependencies" and "peerDependencies"
    syncpack list-mismatches --dev --peer

    set-semver-ranges

    Ensure dependency versions used within "dependencies", "devDependencies", and "peerDependencies" follow a consistent format.

    See semverGroups if you have advanced requirements.

    Options
    -s, --source [pattern]      glob pattern for package.json files to read from
    -r, --semver-range <range>  see supported ranges below. defaults to ""
    -f, --filter [pattern]      only include dependencies whose name matches this regex
    -p, --prod                  include dependencies
    -d, --dev                   include devDependencies
    -P, --peer                  include peerDependencies
    -R, --resolutions           include resolutions (yarn)
    -o, --overrides             include overrides (npm)
    -O, --pnpmOverrides         include overrides (pnpm)
    -w, --workspace             include locally developed package versions
    -i, --indent [value]        override indentation. defaults to "  "
    -r, --semver-range <range>  see supported ranges below. defaults to ""
    -c, --config <path>         path to a syncpack config file
    -h, --help                  display help for command
    
    Examples
    # uses defaults for resolving packages
    syncpack set-semver-ranges
    # uses packages defined by --source when provided
    syncpack set-semver-ranges --source "apps/*/package.json"
    # multiple globs can be provided like this
    syncpack set-semver-ranges --source "apps/*/package.json" --source "core/*/package.json"
    # uses dependencies regular expression defined by --filter when provided
    syncpack set-semver-ranges --filter "typescript|tslint"
    # use ~ range instead of default ""
    syncpack set-semver-ranges --semver-range ~
    # set ~ range in "devDependencies"
    syncpack set-semver-ranges --dev --semver-range ~
    # set ~ range in "devDependencies" and "peerDependencies"
    syncpack set-semver-ranges --dev --peer --semver-range ~
    # indent package.json with 4 spaces instead of 2
    syncpack set-semver-ranges --indent "    "

    🛠 Configuration File

    Creating a configuration file is optional, syncpack will search up the directory tree in the following places:

    • a syncpack property in package.json
    • a .syncpackrc file in JSON or YAML format
    • a .syncpackrc.json, .syncpackrc.yaml, .syncpackrc.yml, .syncpackrc.js, or .syncpackrc.cjs file
    • a syncpack.config.js or syncpack.config.cjs CommonJS module exporting an object
    • a config.syncpack property in package.json

    If you want to specify a path to a configuration file, overriding the discovered configuration file (if present), you can use the --config option.

    Default Configuration

    {
      "dev": true,
      "filter": ".",
      "indent": "  ",
      "overrides": true,
      "peer": true,
      "pnpmOverrides": true,
      "prod": true,
      "resolutions": true,
      "workspace": true,
      "semverGroups": [],
      "semverRange": "",
      "sortAz": [
        "contributors",
        "dependencies",
        "devDependencies",
        "keywords",
        "peerDependencies",
        "resolutions",
        "scripts"
      ],
      "sortFirst": ["name", "description", "version", "author"],
      "source": [],
      "versionGroups": []
    }

    dev, peer, prod, resolutions, overrides, pnpmOverrides, and workspace

    Whether to search within devDependencies, peerDependencies, dependencies, resolutions (Yarn), overrides (npm), pnpmOverrides (pnpm), and the version property of the package.json files of your own packages developed within your workspace respectively.

    All of these locations are searched by default but they can be disabled individually in your config file. If any are set via the command line options --dev, --peer, --prod, --resolutions, --overrides, --pnpmOverrides, or --workspace then only the options you provide will be searched.

    filter

    A string which will be passed to new RegExp() to match against package names that should be included.

    ⚠️ filter was originally intended as a convenience to be used from the command line to filter the output of syncpack list, it is not recommended to add this to your config file to manage your project more generally.

    Instead use versionGroups and/or semverGroups.

    indent

    The character(s) to be used to indent your package.json files when writing to disk.

    semverRange

    Defaulted to "" to ensure that exact dependency versions are used instead of loose ranges, but this can be overridden in your config file or via the --semver-range command line option.

    Supported Ranges

    <  <1.4.2
    <= <=1.4.2
    "" 1.4.2
    ~  ~1.4.2
    ^  ^1.4.2
    >= >=1.4.2
    >  >1.4.2
    *  *
    

    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. There is no equivalent CLI Option for this configuration.

    sortFirst

    When using the format command, determines which fields within package.json files should appear at the top, and in what order. There is no equivalent CLI Option for this configuration.

    source

    Defaults to ["package.json", "packages/*/package.json"] to match most Projects using Lerna or Yarn Workspaces, but this can be overridden in your config file or via multiple --source command line options. Supports any patterns supported by glob.

    versionGroups

    The most common use case for version groups is when some of the packages in your Monorepo are considered alpha (or legacy). Since those packages are much further ahead (or behind) the other packages, the dependencies within those packages need to be managed differently to the rest of the Monorepo.

    Your alpha packages might use unstable versions of some dependencies, while the rest of the repo might need to remain on stable versions.

    You don't want mismatches within your alpha packages, you don't want mismatches within the other packages, but you do want those groups to use different versions to each other and not have syncpack make them all the same.

    In the following example, 2 of our packages are using different versions of react and react-dom to the rest of the project.

    {
      "versionGroups": [
        {
          "dependencies": ["react", "react-dom"],
          "packages": ["@alpha/server", "@alpha/ui"]
        }
      ]
    }

    👋 The dependencies and packages fields are processed using minimatch, so the above example can also be written as "packages": ["@alpha/**"].

    syncpack will make ensure that:

    • The versions of react and react-dom are the same within @alpha/server and @alpha/ui.
    • The versions of react and react-dom are the same across every package except @alpha/server and @alpha/ui.
    • The versions of react and react-dom within @alpha/server and @alpha/ui can be different to the other packages in the monorepo.
    • The versions of every other dependency in the monorepo (eg lodash) are the same across every package including @alpha/server and @alpha/ui.

    Each dependency can only belong to one version group, the first rule which matches a given dependency and package will apply.

    You can be quite granular with these rules, so the partitioning doesn't have to apply to an entire package:

    • A specific dependency in a specific package.
    • A specific dependency in some specific packages only.
    • Any dependency who name matches a pattern such as @aws-sdk/**.

    See semverGroups for more examples, they work the same way.

    versionGroup.dependencies

    Required. An array of minimatch glob patterns which should match the key of dependencies defined in your package.json files.

    Pattern Matches
    ["**"] Any dependency
    ["@aws-sdk/**"] Any dependency with the scope @aws-sdk
    ["react", "react-dom"] Specific dependencies by name

    versionGroup.packages

    Required. An array of minimatch glob patterns which should match the name property of packages developed within your monorepo.

    Pattern Matches
    ["**"] Any package
    ["@my-repo/**"] Any package with the scope @my-repo
    ["my-server", "my-client"] Specific packages by name

    versionGroup.dependencyTypes

    Optional. If set, will result in only the dependency types included in that array being considered a match for this version group.

    In this example we define that all dependencies within peerDependencies in the repo must match, regardless of what versions of the same dependencies might be used in dependencies or devDependencies.

    {
      "versionGroups": [
        {
          "dependencies": ["**"],
          "dependencyTypes": ["peerDependencies"],
          "packages": ["**"]
        }
      ]
    }

    versionGroup.isBanned

    Remove dependencies which you've decided should never be allowed.

    {
      "versionGroups": [
        {
          "dependencies": ["never-gonna"],
          "isBanned": true,
          "packages": ["**"]
        }
      ]
    }

    versionGroup.isIgnored

    Have syncpack ignore these dependencies completely.

    {
      "versionGroups": [
        {
          "dependencies": ["**"],
          "isIgnored": true,
          "packages": ["oops-moment", "workaround"]
        }
      ]
    }

    versionGroup.pinVersion

    Pin the version of all dependencies in this group to match this specific version you've defined.

    {
      "versionGroups": [
        {
          "dependencies": ["@aws-sdk/**"],
          "packages": ["**"],
          "pinVersion": "3.55.0"
        }
      ]
    }

    semverGroups

    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.

    Example use cases

    1: Every dependency of @myrepo/library should have a semver range of ~, regardless of what the rest of the monorepo uses:

    {
      "semverGroups": [
        {
          "range": "~",
          "dependencies": ["**"],
          "packages": ["@myrepo/library"]
        }
      ]
    }

    2: Every dependency of @myrepo/library whose name matches @alpha/** should have a semver range of ^, regardless of what the rest of that package or the rest of the monorepo uses:

    {
      "semverGroups": [
        {
          "range": "^",
          "dependencies": ["@alpha/**"],
          "packages": ["@myrepo/library"]
        }
      ]
    }

    3: Every dependency in the monorepo whose name matches @alpha/** should have a semver range of ~, regardless of what the rest of the monorepo uses:

    {
      "semverGroups": [
        {
          "range": "~",
          "dependencies": ["@alpha/**"],
          "packages": ["**"]
        }
      ]
    }

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

    {
      "semverGroups": [
        {
          "range": "",
          "dependencyTypes": [
            "dependencies",
            "resolutions",
            "overrides",
            "pnpmOverrides",
            "workspace"
          ],
          "dependencies": ["**"],
          "packages": ["**"]
        },
        {
          "range": "~",
          "dependencyTypes": ["devDependencies"],
          "dependencies": ["**"],
          "packages": ["**"]
        },
        {
          "range": "^",
          "dependencyTypes": ["peerDependencies"],
          "dependencies": ["**"],
          "packages": ["**"]
        }
      ]
    }

    semverGroup.range

    Which of the Supported Ranges this group should use.

    semverGroup.dependencies

    Works the same as versionGroup.dependencies.

    semverGroup.isIgnored

    Works the same as versionGroup.isIgnored.

    semverGroup.packages

    Works the same as versionGroup.packages.

    semverGroup.dependencyTypes

    Works the same as versionGroup.dependencyTypes.

    🕵🏾‍♀️ Resolving Packages

    package.json files are resolved in this order of precendence:

    1. If --source glob patterns are provided, use those.
    2. If using Yarn Workspaces, read workspaces from ./package.json.
    3. If using Lerna, read packages from ./lerna.json.
    4. If using Pnpm, read packages from ./pnpm-workspace.yaml.
    5. Default to 'package.json' and 'packages/*/package.json'.

    👋 Always add quotes around your --source patterns [more info].

    🙋🏿‍♀️ Getting Help

    Get help with issues by creating a Bug Report or discuss ideas by opening a Feature Request.

    👀 Other Projects

    If you find my Open Source projects useful, please share them ❤️

    Install

    npm i syncpack

    DownloadsWeekly Downloads

    102,424

    Version

    8.4.11

    License

    MIT

    Unpacked Size

    163 kB

    Total Files

    99

    Last publish

    Collaborators

    • fold_left