Skip to content

feat(json): add helper metadata to output #322

@robinvw1

Description

@robinvw1

Description

Feature request: machine-readable output of affected file paths for fix and format

First of all: @JamieMason this is a great tool!

Problem

When integrating syncpack into a programmatic workflow (e.g. an Nx conformance generator or a CI
script), there's no way to know which package.json files were actually modified after running
syncpack fix or syncpack format - short of doing a full before/after content diff yourself.

The current --dry-run output is human-readable only:

  • fix --dry-run reports dependency names and version mismatches, with no file paths.
  • format --dry-run reports the package name field (e.g. integration at package.json), not
    the file path — so resolving it back to a path requires a secondary lookup across all
    package.json files.

Proposed solution

Add a --json (or --reporter json) flag to fix and format that emits a structured JSON
summary to stdout, including at minimum the list of file paths that were (or would be, with
--dry-run) written to disk.

Example output:

{
  "changedFiles": [
    "apps/service-a/package.json",
    "libs/shared/package.json"
  ]
}

Usecase

Without this, tools that wrap syncpack must snapshot all package.json contents before running,
then re-read every file from disk afterwards to detect what changed. This is wasteful as syncpack
already has this information internally during execution.

Exposing it via structured output would allow wrappers to skip the before/after diff entirely and
trust syncpack's own change tracking.

Suggested Solution

CLI usage

# Apply fixes and get a JSON summary of what changed
syncpack fix --reporter json

# Preview what would change without writing to disk
syncpack fix --dry-run --reporter json

# Compose with format in one pipeline
syncpack fix --reporter json && syncpack format --reporter json

CLI output

Normal (human-readable) output currently goes to stdout. With --reporter json, stdout becomes machine-parseable and stderr retains any warnings/errors:

syncpack fix --reporter json

{
  "command": "fix",
  "changedFiles": [
    "apps/billing/package.json",
    "apps/invoicing/package.json"
  ],
  "changes": [
    {
      "file": "apps/billing/package.json",
      "dependency": "kleur",
      "from": "4.1.4",
      "to": "4.1.5"
    },
    {
      "file": "apps/invoicing/package.json",
      "dependency": "kleur",
      "from": "4.1.4",
      "to": "4.1.5"
    }
  ]
}

syncpack format --reporter json

{
  "command": "format",
  "changedFiles": [
    "apps/integration/package.json"
  ],
  "changes": [
    {
      "file": "apps/integration/package.json",
      "reason": "PropertyIsNotSortedAz",
      "property": ".dependencies"
    }
  ]
}

syncpack fix --dry-run --reporter json — identical shape, but nothing is written to disk and a dryRun: true flag is included:

{
  "command": "fix",
  "dryRun": true,
  "changedFiles": [
    "apps/billing/package.json"
  ],
  "changes": [...]
}

Config file

A reporter option in .syncpackrc.json sets the default, so CI pipelines don't need to pass the flag every time:

{
  "$schema": "./node_modules/syncpack/schema.json",
  "reporter": "json",
  "sortFirst": ["name", "version", "..."],
  "versionGroups": [...]
}

Multiple reporter targets would also be useful (e.g. human output to stderr, JSON to stdout):

{
  "reporter": ["pretty", "json"]
}

Optional comments

No response

Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions