npm package: @npvd/npvd
Description: Identify version differences between node package lockfile revisions
Author: Matt Mower
Latest version: 0.4.2

## @npvd/npvd

[![npm](https://img.shields.io/npm/v/@npvd/npvd)](https://www.npmjs.com/package/@npvd/npvd)
[![NPM](https://img.shields.io/npm/l/@npvd/npvd)](./LICENSE)

Find version differences between all packages installed in Node.js projects. Compares lock files either by file path or Git revision. Supported package manager lock file versions include:

- NPM `package-lock.json` lock files with `lockfileVersion` value `2` or `3`. In practice, these lock files are generated by NPM versions 7 and newer.
- PNPM `pnpm-lock.yaml` lock files with `lockfileVersion` value `6` or `9`. In practice, these lock files are generated by PNPM versions 8 and newer (and technically version 7 as well, but opt-in was required).

Several outputs are possible, including console, CSV, and JSON.

#### Sample output

Direct dependency version changes that occurred in this project between Git tags v0.1.0 and v0.2.0:

```
$ npvd --git v0.1.0 v0.2.0 --direct-only
@eslint/js: 9.18.0 -> 9.24.0
@pnpm/lockfile-file: (added) -> 9.1.3
@pnpm/lockfile-walker: (added) -> 9.0.4
@pnpm/lockfile.fs: 1001.1.1 -> 1001.1.9
@pnpm/lockfile.utils: 1001.0.1 -> (removed)
@pnpm/lockfile.walker: 1001.0.1 -> 1001.0.7
@types/eslint__js: 8.42.3 -> (removed)
@types/node: 20.17.12 -> 20.17.30
commander: 13.0.0 -> 13.1.0
eslint-config-prettier: 9.1.0 -> 10.1.2
eslint-plugin-prettier: 5.2.1 -> 5.2.6
globals: 15.14.0 -> 16.0.0
prettier: 3.4.2 -> 3.5.3
publint: 0.3.1 -> 0.3.11
tsup: 8.3.5 -> 8.4.0
tsx: 4.19.2 -> 4.19.3
typescript: 5.7.3 -> 5.8.3
typescript-eslint: 8.19.1 -> 8.29.1
```

### Quick start

Local installation and execution; compare Git tags `tag1` and `tag2` in current repository:

```
$ npm install --save-dev @npvd/npvd
$ npx npvd --git tag1 tag2
```

Global installation and execution; compare package lock files in directories `a` and `b`:

```
$ npm install -g @npvd/npvd
$ npvd a/package-lock.json b/package-lock.json
```

See more complete usage instructions and examples below.

### Usage

```
Usage: npvd [options] <from> <to>

Arguments:
  from                    From lock file or git commit
  to                      To lock file or git commit

Options:
  --mode <pkgmgr>         Package manager (npm, pnpm) (default: "npm")
  --include <deptype>     Dependency types to include (prod, dev, optional, peer)
  --omit <deptype>        Dependency types to omit (dev, optional, peer)
  --direct-only           Only include direct dependencies
  --git                   Interpret <from> and <to> as git commits
  --git-lock-file <path>  Path to lock file relative to repository root
  --format <format>       Output format (text, json, csv) (default: "text")
  --json-spaces <num>     Number of spaces to use for indentated JSON output
  --eol <eol>             End of line to use for file output (LF, CRLF) (default: "LF")
  --out-file <path>       File path including file name where output should be written
  -h, --help              display help for command
```

#### Example: diff two npm lock files and output to the console

Output all changes

```sh
$ npvd a/package-lock.json b/package-lock.json
```

Output only changes to direct, prod dependencies

```sh
$ npvd a/package-lock.json b/package-lock.json --include prod --direct-only
```

#### Example: diff two npm lock files by git revision and output to the console as indented json

Output all changes

```sh
$ npvd 2753c5b main --git --format json --json-spaces 2
```

Output only changes to direct, non-dev dependencies

```sh
$ npvd 2753c5b main --git --format json --json-spaces 2 --omit dev --direct-only
```

#### Example: diff two pnpm lock files and output to a CSV file

Output all changes

```sh
$ npvd a/pnpm-lock.yaml b/pnpm-lock.yaml --mode pnpm --format csv --out-file version-diff.csv
```

Output only changes to direct, prod dependencies

```sh
$ npvd a/pnpm-lock.yaml b/pnpm-lock.yaml --mode pnpm --include prod --direct-only --format csv --out-file version-diff.csv
```

### Dependency trees

Note that npm flattens packages in `node_modules` when possible. The original dependency tree is not preserved. For example if `module-x` is a dependency of `module-a` and `module-b`, and a common version of `module-x` can satisfy both `module-a` and `module-b` version requirements, then `module-x` is added directly to `node_modules` instead of being nested under `module-a` and `module-b`. The package lock file maintains version information in this flattened structure as well. It is not a goal of this project to reconstruct dependency trees. Path and version information output by this tool are based on the final dependency structure computed by the package manager. It _is_ still possible to identify whether a dependency is a direct or transitive dependency (see CLI flag `--direct-only`); it's just that transitive dependencies may or may not have path information that indicate their parent packages.

pnpm does not flatten packages, so the path information output by this tool _happens_ to also represent the original dependency tree.

### Known limitations

1. Including or omitting `peer` type dependencies is not supported in pnpm mode. Those dependencies will be included automatically with their associated `prod`, `dev`, and `optional` dependencies.