# syncpack

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

[![NPM version](http://img.shields.io/npm/v/syncpack.svg?style=flat-square)](https://www.npmjs.com/package/syncpack)
[![NPM downloads](http://img.shields.io/npm/dm/syncpack.svg?style=flat-square)](https://www.npmjs.com/package/syncpack)
[![Build Status](http://img.shields.io/travis/JamieMason/syncpack/master.svg?style=flat-square)](https://travis-ci.org/JamieMason/syncpack)
[![Maintainability](https://api.codeclimate.com/v1/badges/516439365fdd0e3c6526/maintainability)](https://codeclimate.com/github/JamieMason/syncpack/maintainability)

## Table of Contents

- [🌩 Installation](#-installation)
- [📝 Commands](#-commands)
  - [fix-mismatches](#fix-mismatches)
  - [format](#format)
  - [list](#list)
  - [list-mismatches](#list-mismatches)
  - [set-semver-ranges](#set-semver-ranges)
- [🛠 Configuration File](#-configuration-file)
- [🕵🏾‍♀️ Resolving Packages](#️-resolving-packages)
- [🙋🏿‍♀️ Getting Help](#️-getting-help)
- [👀 Other Projects](#-other-projects)

## 🌩 Installation

    npm install --global syncpack

## 📝 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`.

<details>
<summary>Options</summary>

    -s, --source [pattern]  glob pattern for package.json files to read from
    -p, --prod              include dependencies
    -d, --dev               include devDependencies
    -P, --peer              include peerDependencies
    -f, --filter [pattern]  regex for dependency filter
    -i, --indent [value]    override indentation. defaults to "  "
    -h, --help              output usage information

</details>

<details>
<summary>Examples</summary>

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

</details>

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

<details>
<summary>Options</summary>

    -s, --source [pattern]  glob pattern for package.json files to read from
    -i, --indent [value]    override indentation. defaults to "  "
    -h, --help              output usage information

</details>

<details>
<summary>Examples</summary>

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

</details>

### list

List all dependencies required by your packages.

<details>
<summary>Options</summary>

    -s, --source [pattern]  glob pattern for package.json files to read from
    -p, --prod              include dependencies
    -d, --dev               include devDependencies
    -P, --peer              include peerDependencies
    -f, --filter [pattern]  regex for dependency filter
    -h, --help              output usage information

</details>

<details>
<summary>Examples</summary>

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

</details>

### list-mismatches

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

<details>
<summary>Options</summary>

    -s, --source [pattern]  glob pattern for package.json files to read from
    -p, --prod              include dependencies
    -d, --dev               include devDependencies
    -P, --peer              include peerDependencies
    -f, --filter [pattern]  regex for dependency filter
    -h, --help              output usage information

</details>

<details>
<summary>Examples</summary>

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

</details>

### set-semver-ranges

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

<details>
<summary>Options</summary>

    -s, --source [pattern]      glob pattern for package.json files to read from
    -p, --prod                  include dependencies
    -d, --dev                   include devDependencies
    -P, --peer                  include peerDependencies
    -f, --filter [pattern]      regex for dependency filter
    -i, --indent [value]        override indentation. defaults to "  "
    -r, --semver-range <range>  see supported ranges below. defaults to ""
    -h, --help                  output usage information

</details>

<details>
<summary>Examples</summary>

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

</details>

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

### Default Configuration

```json
{
  "dev": true,
  "filter": ".",
  "indent": "  ",
  "peer": true,
  "prod": true,
  "semverRange": "",
  "source": ["package.json", "packages/*/package.json"]
}
```

### `dev`, `peer`, and `prod`

Whether to search within `devDependencies`, `peerDependencies`, and `dependencies` 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`, or `--prod` 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.

### `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
*  *
```

### `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](https://github.com/isaacs/node-glob).

## 🕵🏾‍♀️ Resolving Packages

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

1.  If `--source` [glob patterns](https://github.com/isaacs/node-glob#glob-primer) are provided, use those.
2.  If using [Yarn Workspaces](https://yarnpkg.com/lang/en/docs/workspaces/), read `workspaces` from `./package.json`.
3.  If using [Lerna](https://lerna.js.org/), read `packages` from `./lerna.json`.
4.  If using [Pnpm](https://pnpm.js.org/), read `packages` from `./pnpm-workspace.yaml`.
5.  Default to `'package.json'` and `'packages/*/package.json'`.

## 🙋🏿‍♀️ Getting Help

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

[bug report]: https://github.com/JamieMason/syncpack/issues/new?template=bug_report.md
[feature request]: https://github.com/JamieMason/syncpack/issues/new?template=feature_request.md

## 👀 Other Projects

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

- [**eslint-formatter-git-log**](https://github.com/JamieMason/eslint-formatter-git-log)<br>ESLint Formatter featuring
  Git Author, Date, and Hash
- [**eslint-plugin-move-files**](https://github.com/JamieMason/eslint-plugin-move-files)<br>Move and rename files while
  keeping imports up to date
- [**eslint-plugin-prefer-arrow-functions**](https://github.com/JamieMason/eslint-plugin-prefer-arrow-functions)<br>Convert
  functions to arrow functions
- [**ImageOptim-CLI**](https://github.com/JamieMason/ImageOptim-CLI)<br>Automates ImageOptim, ImageAlpha, and JPEGmini
  for Mac to make batch optimisation of images part of your automated build process.
- [**Jasmine-Matchers**](https://github.com/JamieMason/Jasmine-Matchers)<br>Write Beautiful Specs with Custom Matchers
- [**karma-benchmark**](https://github.com/JamieMason/karma-benchmark)<br>Run Benchmark.js over multiple Browsers, with
  CI compatible output
- [**self-help**](https://github.com/JamieMason/self-help#readme)<br>Interactive Q&A Guides for Web and the Command Line
