Skip to content

zmrishh/depopsy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

8 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Depopsy πŸš€

The npm doctor for dependency chaos.

Understand why your dependencies are bloated β€” and fix them safely.

npm version npm downloads Node.js >=18 License: MIT Supports npm Β· yarn Β· pnpm


The Problem

Modern JavaScript projects silently accumulate multiple versions of the same package. After a few months of adding dependencies, you might have lodash@4.17.19 and lodash@4.17.21 installed simultaneously β€” pulled in by different tools like eslint, jest, or next.

This leads to:

  • 🐒 Slower installs β€” npm install / CI pipelines download and extract duplicate packages
  • πŸ“¦ Larger bundles β€” your end users download the bloat too
  • πŸ› Subtle runtime bugs β€” packages that check instanceof silently break when two versions exist

npm dedupe tells you what is duplicated. depopsy tells you why β€” and fixes it safely.


Quick Start

Zero install required. Run it at the root of any npm, yarn, or pnpm project:

npx depopsy

For a quick 3-line summary:

npx depopsy --simple

Example Output

Analyzing large dependency graph...
Detected Package Manager: npm

πŸ“¦ Dependency Health Report
──────────────────────────────────────────────────

🚨 Problem:
   You have 19 duplicate dependencies
   β†’ ~1.89 MB wasted on disk
   β†’ Slower installs, larger bundles, subtle runtime bugs

πŸ”₯ Top Root Causes  (you can act on)
   These are the packages pulling in most duplicate dependencies.

  1. jest  β†’ 19 duplicate packages

   βž” These top root causes account for ~89% of your duplication.

🎯 Why this matters
  Β· Multiple versions of the same package increase bundle size
  Β· Slows npm install / pnpm install / CI pipelines
  Β· Can cause subtle runtime bugs when packages check instanceof

🧠 What you should do

  β–Ά jest
  Confidence: LOW β€” manual review required
  Introduces: ansi-styles, chalk, ansi-regex, semver (+15 more)
  β†’ Test tooling often bundles its own utility versions.
  β†’ Upgrade jest to latest β€” may resolve 19 duplicate chains.

⚑ Quick Fix
   Run:  npx depopsy fix
   (applies 0 SAFE fixes automatically β€” no breaking changes)

πŸ“Š Summary
──────────────────────────────────────────────────
  βœ” SAFE issues:  0  (auto-fixable)
  βœ– RISKY issues: 19  (manual review)

──────────────────────────────────────────────────
πŸ’‘ Tip: Even well-maintained projects have duplicates.
   This tool explains *why* β€” not just what.

CLI Reference

Command Description
npx depopsy Full dependency health report
npx depopsy --simple Top 3 root causes only
npx depopsy --verbose Full breakdown of every group
npx depopsy --top <n> Limit root cause output to top N groups
npx depopsy --json JSON output for CI/CD pipelines
npx depopsy --ci Minimal JSON with correct exit codes
npx depopsy fix Dry-run: preview safe deduplication fixes
npx depopsy fix --yes Apply fixes directly to package.json
npx depopsy trace <pkg> Trace which top-level dep introduces <pkg>

Exit Codes

Code Meaning
0 Success β€” no duplicates found
1 Duplicates found
2 Fatal error (no lockfile, parse failure, etc.)

How It Works

1. Parses your lockfile  β†’  package-lock.json, yarn.lock, or pnpm-lock.yaml
2. Builds a dependency graph  β†’  maps every package to its introducers
3. Detects duplicates  β†’  packages installed at multiple versions
4. Identifies root causes  β†’  which top-level dep (eslint, jest, next) is responsible
5. Suggests safe fixes  β†’  only semver-compatible consolidations

Root Cause Attribution

The attribution engine uses a 3-layer priority system to find the most actionable signal:

  1. roots[] β€” Pre-computed top-level introducers via graph traversal (most accurate)
  2. parents[] β€” Immediate dependents (closer signal than full ancestor chain)
  3. ancestors[] β€” Full flattened chain (last resort, only when no better signal exists)

Low-level utility packages (chalk, semver, minimatch, glob, etc.) are automatically suppressed from root cause output β€” they are always indirect symptoms, never causes.


Features

Feature Detail
βœ… Multi-lockfile npm (package-lock.json), yarn (yarn.lock), pnpm (pnpm-lock.yaml)
βœ… Root cause analysis Identifies which top-level dep pulls in each duplicate
βœ… Safe fixes only Backs up package.json before writing; never touches RISKY diffs
βœ… CI/CD ready --json and --ci flags with correct exit codes
βœ… Zero config Works instantly in any project root β€” no setup required
βœ… Monorepo aware Skips internal workspace packages (link:, workspace:, file:)
βœ… Disk waste measurement Actual on-disk byte measurement of duplicate package directories
βœ… Package manager detection Auto-detects npm / yarn / pnpm from lockfile presence
βœ… Yarn v1 + v2+ Handles both classic and modern Yarn lockfile formats
βœ… pnpm v5–v9 Handles all pnpm lockfile versions including v9 snapshots

The fix Command

depopsy fix only touches SAFE duplicates β€” packages where all versions share the same major version (semver-compatible).

# Preview what would change (no files modified)
npx depopsy fix

# Apply changes to package.json
npx depopsy fix --yes

After running fix --yes, you must reinstall to apply the overrides to your lockfile:

npm install    # or yarn install / pnpm install

What it writes

Package manager What gets written
npm "overrides" in package.json
yarn "resolutions" in package.json
pnpm "pnpm.overrides" in package.json

A backup of your original package.json is saved to .depopsy-backup/ before any write.


The trace Command

Trace exactly which top-level dependencies are responsible for pulling in a given package:

npx depopsy trace semver
Tracing "semver" through dependency graph...

πŸ” Trace: semver
──────────────────────────────────────────────────

  Versions found: 5.7.2, 7.5.4, 7.6.0
  Safety: RISKY

  semver is introduced by:
    β–Ά jest
    β–Ά eslint
    β–Ά @babel/core

  Per-version breakdown:
    5.7.2 β€” required by: node-semver, validate-npm-package-version
    7.5.4 β€” required by: jest-runner, jest-resolve
    7.6.0 β€” required by: eslint, @babel/core

──────────────────────────────────────────────────
  ⚠  No auto-fix available β€” versions span multiple majors.

CI/CD Integration

GitHub Actions

- name: Check for duplicate dependencies
  run: npx depopsy --ci
  # Exits 1 if duplicates found, 0 if clean

JSON output for custom scripting

npx depopsy --json > dep-report.json
{
  "summary": {
    "total": 19,
    "safe": 4,
    "risky": 15,
    "wasteKB": "1934.22"
  },
  "rootCauses": [...],
  "duplicates": [...],
  "suggestions": [...]
}

FAQ

Q: How is this different from npm dedupe?

npm dedupe reorganizes node_modules at install time but doesn't prevent the problem from recurring. depopsy analyzes your lockfile to explain the root cause and writes overrides/resolutions to your package.json β€” so the deduplication survives a fresh npm install.

Q: Is it safe to run on production projects?

Yes. The analyze and trace commands are fully read-only. The fix command defaults to a dry-run β€” you must explicitly pass --yes to make changes, and it always creates a backup first.

Q: Does it work with workspaces / monorepos?

Yes. It automatically detects workspace packages and excludes them from root cause attribution (they use link:, workspace:, or file: version strings in lockfiles).

Q: Why does it show "RISKY" for some duplicates?

RISKY means the duplicate versions span multiple major versions (e.g., react@17 and react@18). These cannot be safely auto-aligned because major version bumps can include breaking changes. Use depopsy trace <pkg> to understand which dependency is causing it.

Q: Why don't I see semver or chalk as root causes?

These are leaf utility packages β€” they are always pulled in transitively, never directly causing bloat. depopsy suppresses them from root cause output to keep results actionable. Use --verbose or trace to inspect them.


Requirements

  • Node.js >= 18.0.0
  • A project with at least one lockfile: package-lock.json, yarn.lock, or pnpm-lock.yaml

Contributing

git clone https://github.com/zmrishh/depopsy
cd depopsy
npm install
npm test

Please open an issue before submitting a pull request for significant changes.


License

MIT Β© 2026 depopsy contributors


Built with ❀️ for the open-source JavaScript ecosystem.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors