Dependency Doctor - Heal Your Package Problems
🎯 When to Use This Skill
Use when experiencing:
-
Security vulnerabilities in dependencies
-
Version conflicts ("dependency hell")
-
Broken builds after updates
-
Slow install times
-
Large node_modules/vendor folders
-
"Works on my machine" issues
-
License compliance concerns
⚡ Quick Health Check (30 seconds)
Universal Diagnosis Commands:
JavaScript/Node.js
npm audit npm outdated npm ls --depth=0
Python
pip check pip list --outdated safety check
Java
mvn dependency:tree mvn versions:display-dependency-updates
Go
go mod tidy go list -m -u all
Ruby
bundle audit bundle outdated
.NET
dotnet list package --vulnerable dotnet list package --outdated
Rust
cargo audit cargo outdated
🔍 Common Dependency Diseases & Cures
- Security Vulnerabilities 🚨
WITH MCP (Security Scanner):
"Scan my dependencies for security vulnerabilities" "Fix all high-severity security issues"
WITHOUT MCP:
Diagnosis:
JavaScript
npm audit --json | jq '.metadata.vulnerabilities'
Python
pip install safety safety check --json
Ruby
gem install bundler-audit bundle audit check
Treatment:
Auto-fix (JavaScript)
npm audit fix
Force fixes (use carefully!)
npm audit fix --force
Manual fix for specific package
npm install package-name@latest
Python manual update
pip install --upgrade package-name
Prevention:
// package.json - Add security check to CI { "scripts": { "security": "npm audit --audit-level=moderate", "preinstall": "npm audit" } }
- Version Conflicts (Dependency Hell) 🔥
Symptoms:
-
"Cannot resolve dependency tree"
-
"Peer dependency not satisfied"
-
Different versions required by different packages
Diagnosis:
Find conflicts
npm ls package-name
See why a package is installed
npm explain package-name
Python conflicts
pip check pipdeptree -p package-name
Treatment:
JavaScript - Resolution strategies
1. Clean install
rm -rf node_modules package-lock.json npm install
2. Force resolutions (package.json)
{ "overrides": { "package-name": "1.2.3" } }
3. Use npm-force-resolutions
npm install --save-dev npm-force-resolutions
Python - Use virtual environments
python -m venv myenv source myenv/bin/activate pip install -r requirements.txt
- Bloated Dependencies 🎈
Diagnosis - Find the Culprits:
JavaScript - Analyze bundle size
npm install -g npm-check npm-check
Or use disk usage
du -sh node_modules/* | sort -hr | head -20
Analyze what's using space
npx webpack-bundle-analyzer stats.json
Treatment - Diet Plan:
// 1. Find lighter alternatives const HEAVY_TO_LIGHT = { moment: 'dayjs', // 67kb → 2kb lodash: 'lodash-es', // Tree-shakeable request: 'node-fetch', // 300kb → 25kb bluebird: 'native', // Use native promises jquery: 'vanilla', // No dependency };
// 2. Import only what you need // BAD import _ from 'lodash';
// GOOD import debounce from 'lodash/debounce';
// 3. Lazy load heavy dependencies const heavyLib = () => import('heavy-library');
Bundle Size Budget:
// package.json { "bundlesize": [ { "path": "./dist/app.js", "maxSize": "100 kB" } ] }
- Outdated Dependencies 📅
Safe Update Strategy:
1. Check what needs updating
npm outdated
2. Update in order of safety
Patch versions (1.0.x) - Usually safe
npm update
Minor versions (1.x.0) - Check changelog
npm install package@^1
Major versions (x.0.0) - Read migration guide
npm install package@latest
3. Test after each update
npm test
Automated Updates with Checks:
GitHub Dependabot config
.github/dependabot.yml
version: 2 updates:
- package-ecosystem: 'npm' directory: '/' schedule: interval: 'weekly' open-pull-requests-limit: 10 groups: minor-and-patch: patterns: - '*' update-types: - 'minor' - 'patch'
- Ghost Dependencies 👻
Find Unused Dependencies:
JavaScript
npx depcheck
Python
pip install pip-autoremove pip-autoremove -l
Result shows unused packages
Clean Up:
Remove unused
npm uninstall package-name
Or use depcheck to auto-remove
npx depcheck --json | jq '.dependencies[]' | xargs npm uninstall
📊 Dependency Management Best Practices
- Lock Files Are Sacred
ALWAYS commit lock files
git add package-lock.json # npm git add yarn.lock # yarn git add pnpm-lock.yaml # pnpm git add Pipfile.lock # Python pipenv git add go.sum # Go
Reproduce exact environment
npm ci # Instead of npm install
- Dependency Hygiene Routine
// Weekly routine const weeklyMaintenance = async () => { // 1. Security check await exec('npm audit');
// 2. Remove unused await exec('npx depcheck');
// 3. Update patch versions await exec('npm update');
// 4. Check for major updates await exec('npm outdated');
// 5. Clean cache await exec('npm cache clean --force');
// 6. Deduplicate await exec('npm dedupe'); };
- Version Range Strategies
{ "dependencies": { // Exact version (safest, least flexible) "critical-lib": "1.2.3",
// Patch updates only (recommended for prod)
"stable-lib": "~1.2.3", // 1.2.x
// Minor updates (good for dev)
"modern-lib": "^1.2.3", // 1.x.x
// Latest (danger zone!)
"experimental": "*"
} }
🚨 Emergency Procedures
Broken After Update:
1. Rollback immediately
git checkout package-lock.json npm ci
2. Find breaking change
npm ls package-name git diff package-lock.json
3. Pin to working version
npm install package-name@1.2.3 --save-exact
4. File issue and wait for fix
Cannot Install Dependencies:
Nuclear option - clean everything
rm -rf node_modules rm package-lock.json npm cache clean --force npm install
Still broken? Check Node version
node --version nvm use 18 # Use LTS version
Registry issues?
npm config set registry https://registry.npmjs.org/
Production Emergency:
Reproducible builds in Docker
FROM node:18-alpine WORKDIR /app
Copy lock file FIRST
COPY package*.json ./
Use ci for exact versions
RUN npm ci --only=production
Then copy code
COPY . .
CMD ["node", "app.js"]
📈 Dependency Metrics
Track Your Health:
// dependency-health.js const getMetrics = async () => { const metrics = { total: Object.keys(require('./package.json').dependencies).length, outdated: await getOutdatedCount(), vulnerable: await getVulnerabilityCount(), unused: await getUnusedCount(), duplicates: await getDuplicateCount(), size: await getTotalSize(), };
// Calculate health score metrics.health = calculateHealth(metrics);
return metrics; };
function calculateHealth(metrics) { let score = 100;
score -= metrics.vulnerable * 10; // -10 per vulnerability score -= metrics.outdated * 2; // -2 per outdated score -= metrics.unused * 3; // -3 per unused score -= metrics.duplicates; // -1 per duplicate
if (metrics.total > 100) score -= 10; // Too many deps if (metrics.size > 100_000_000) score -= 10; // Too large
return Math.max(0, score); }
🛡️ Dependency Security Policy
Security Policy
Automated Checks
- CI runs
npm auditon every PR - Dependabot creates PRs for security updates
- Weekly security report via GitHub Actions
Severity Levels
- Critical: Fix immediately, hotfix to production
- High: Fix within 24 hours
- Moderate: Fix within 1 week
- Low: Fix in next release
Approved Sources
✅ npm official registry ✅ GitHub packages (our org) ❌ Random GitHub repos ❌ Unverified registries
License Requirements
✅ MIT, Apache 2.0, BSD ⚠️ GPL (check with legal) ❌ Proprietary, AGPL
💊 Preventive Medicine
Dependency Budget:
// dependency-budget.js const BUDGET = { maxDependencies: 50, maxSize: 50_000_000, // 50MB maxDepth: 3, allowedLicenses: ['MIT', 'Apache-2.0', 'BSD'], bannedPackages: ['left-pad', 'is-odd'], };
// Pre-install check function checkBudget(packageName) { const metrics = getCurrentMetrics();
if (metrics.count >= BUDGET.maxDependencies) { throw new Error('Dependency budget exceeded'); }
if (isBanned(packageName)) {
throw new Error(Package ${packageName} is banned);
}
// Check before adding return true; }
Dependency Documentation:
Why This Dependency?
Package: stripe
Purpose: Payment processing Alternatives considered: PayPal SDK, Square Why chosen: Best API, good docs Can we remove?: No, core feature Owner: Payment team
Package: lodash
Purpose: Utility functions Alternatives considered: Ramda, native Why chosen: Team familiarity Can we remove?: Yes, migrate to lodash-es Owner: Frontend team
🎯 Quick Reference Card
Daily health check
alias dephealth='npm audit && npm outdated && npx depcheck'
Emergency fix
alias depfix='rm -rf node_modules package-lock.json && npm cache clean --force && npm install'
Update safely
alias depsafe='npm update && npm test && npm audit'
Full maintenance
alias depmaint='npm audit fix && npm dedupe && npm prune && npx depcheck'
Remember: Dependencies are like medicine - necessary but can have side effects. Use wisely! 💊