DEV Community

Shivam
Shivam

Posted on • Originally published at online-diff.com

How to Compare package.json Files: A Node.js Developer's Guide

You open a pull request to review a dependency update and the diff is a wall of text — 80 lines of package names and version numbers. Your teammate says "just bumped a few deps", but buried in there is a downgraded React version and two new packages nobody discussed.

Manually spotting that by eye is error-prone. A proper side-by-side diff would have caught it in seconds.

Here are four methods for comparing package.json files, when to use each, and a workflow that fits into real code reviews.


Why package.json Comparisons Go Wrong

The obvious ones are easy — a new package name sticks out. The dangerous ones are subtle:

  • A minor version bump (^18.2.0 → ^18.3.0) that pulls in a breaking change via a transitive dependency
  • A peerDependency conflict where two packages need different versions of the same library — causing silent runtime bugs that your test suite won't catch
  • A package silently downgraded during a lockfile resolution
  • A devDependency accidentally moved to dependencies, inflating your production bundle

None of these are obvious from a quick glance at a git diff. They need a proper side-by-side comparison.


Method 1: Git Diff (Fastest)

The go-to for a quick local check before pushing:

git diff main..feature-branch -- package.json
Enter fullscreen mode Exit fullscreen mode

To include more context lines around each change:

git diff -U10 main..feature-branch -- package.json
Enter fullscreen mode Exit fullscreen mode

Always diff the lockfile at the same time — version constraints in package.json can hide transitive changes that only show up in package-lock.json or yarn.lock:

git diff main..feature-branch -- package.json package-lock.json
Enter fullscreen mode Exit fullscreen mode

Best for: Quick checks before pushing. Not great for large files or sharing with teammates — the raw terminal output is hard to read.


Method 2: GitHub Pull Request Diff

If the PR is already open on GitHub:

  1. Go to the Files changed tab
  2. Scroll to package.json
  3. Click the split view icon (two columns) for side-by-side mode

GitHub highlights added lines in green and removed lines in red. For large files, use the File filter dropdown at the top to jump straight to package.json.

Best for: Reviewing a PR before merging. Doesn't help when you want to compare arbitrary branches or files not in an open PR.


Method 3: Online Diff Tools (Most Visual)

For a detailed, shareable comparison — especially useful for large dependency updates or monorepo audits — paste both package.json files into an online diff tool like Online Diff.

Here's what a typical comparison looks like:

// package.json on main branch
"dependencies": {
  "react": "^18.2.0",
  "axios": "^1.4.0",
  "lodash": "^4.17.21"
}

// package.json on feature branch
"dependencies": {
  "react": "^18.3.0",       //  version bumped
  "axios": "^1.4.0",
  "lodash": "^4.17.21",
  "zod": "^3.22.4",         //  new package added
  "date-fns": "^3.0.0"      //  new package added
}
Enter fullscreen mode Exit fullscreen mode

With syntax highlighting and character-level diffs, version bumps and new packages are immediately obvious. You can share the diff URL with your team — useful when the reviewer can't run git locally.

Best for: Detailed dependency audits, sharing with colleagues, comparing files across different repos.


Method 4: npm diff (npm 8+)

npm 8 introduced a built-in diff command:

npm diff -- package.json
Enter fullscreen mode Exit fullscreen mode

You can also compare specific versions of a package:

npm diff --diff=lodash@4.17.20 --diff=lodash@4.17.21
Enter fullscreen mode Exit fullscreen mode

Best for: Comparing installed package versions when investigating what changed between two npm installs. Less useful for branch-to-branch comparisons.


The Security Angle: Why This Matters Beyond Code Review

Dependency diffs are one of the most underused parts of a security review. When a new package is added to your project, you're trusting that:

  • The package author hasn't published malicious code
  • The package's own dependencies are clean
  • The version you're pinning doesn't have a known CVE

A side-by-side diff makes the attack surface visible. When you see "5 new packages added", that's 5 supply chain vectors to evaluate — much easier to spot in a visual diff than buried in 120 lines of JSON.

After reviewing the diff visually, always run:

npm audit
Enter fullscreen mode Exit fullscreen mode

This cross-references your dependencies against the npm advisory database. A version bump that looks harmless in the diff may resolve — or introduce — a known vulnerability.


Handling Monorepos

If you manage multiple package.json files across a monorepo (apps/web/, apps/api/, packages/ui/), script the extraction:

# Extract package.json files from main branch
git show main:apps/web/package.json > web-main.json
git show main:apps/api/package.json > api-main.json
git show main:packages/ui/package.json > ui-main.json

# Then paste each pair into an online diff tool
Enter fullscreen mode Exit fullscreen mode

This is how version drift gets caught — where apps/web is on React 18.2 and packages/ui is still on React 17, causing subtle incompatibilities that only surface at runtime.

For automated checks across all packages:

for dir in packages/*/; do
  echo "=== $dir ==="
  git diff main..feature -- "$dir/package.json"
done
Enter fullscreen mode Exit fullscreen mode

A Real Code Review Workflow

Here's how this fits into a real PR review process:

  1. Developer opens PR with dependency updates
  2. CI runs npm audit — flags any known vulnerabilities
  3. Reviewer extracts both package.json versions and pastes into a diff tool
  4. Reviewer sees at a glance: 2 new packages (zod, date-fns), 1 version bump (react ^18.2.0 → ^18.3.0)
  5. Reviewer checks the CHANGELOG for new packages
  6. Reviewer confirms the React bump is a minor version (safe)
  7. Approve and merge
  8. After merge: npm install, CI tests pass

This takes 3 minutes. Without the diff, it takes 10 minutes of squinting at JSON, and you're still not confident you caught everything.


Key Takeaways

  • Use git diff for fast local checks before pushing
  • Use GitHub's PR view for reviewing changes before merging
  • Use an online diff tool for detailed audits and sharing
  • Always diff the lockfile alongside package.json
  • Run npm audit after any dependency comparison
  • In monorepos, script the extraction to catch version drift across all packages

What's your workflow for reviewing dependency changes? Drop it in the comments — always curious how teams handle this at scale.


Originally published at online-diff.com/blog/compare-package-json

Top comments (0)