Dependency Governance Skill
When to Use This Skill
- Running security audits
- Updating vulnerable packages
- Controlling bundle size
- Setting team dependency policies
- Reviewing PRs that add dependencies
Rule 1 — Audit Before Shipping
# Check for vulnerabilities
npm audit
# Fix automatically (safe changes only)
npm audit fix
# Fix including major version bumps (review carefully)
npm audit fix --force
# Audit production dependencies only
npm audit --omit=dev
AI instruction: Always run npm audit before deploying. Never ship known critical vulnerabilities.
Rule 2 — Understand Severity Levels
critical → Fix immediately. Data exposure, RCE, auth bypass.
high → Fix this sprint. Significant security risk.
moderate → Fix next sprint. Limited exploitability.
low → Fix when convenient. Minimal risk.
info → Informational only.
# Only fail CI on critical/high
npm audit --audit-level=high
# Full report with paths
npm audit --json | node -e "
const d = JSON.parse(require('fs').readFileSync('/dev/stdin','utf8'));
Object.values(d.vulnerabilities)
.filter(v => ['critical','high'].includes(v.severity))
.forEach(v => console.log(v.severity.toUpperCase(), v.name, v.fixAvailable));
"
Rule 3 — Version Pinning Strategy
// package.json — three approaches:
// Exact pin — most predictable, manual updates needed
"react": "18.2.0"
// Patch updates only (^) — safe for most packages
"axios": "^1.6.0" // accepts 1.6.1, 1.7.0 but not 2.0.0
// Minor updates only (~) — conservative
"lodash": "~4.17.21" // accepts 4.17.22 but not 4.18.0
AI instruction: Pin exact versions for critical dependencies (react, react-dom, typescript). Use ^ for utilities. Never use * or latest.
Rule 4 — Evaluating New Dependencies
Before adding ANY new dependency ask:
1. Is it necessary? Can we use a native API instead?
- date-fns vs Intl.DateTimeFormat
- lodash.get vs optional chaining (?.)
- axios vs fetch + a small wrapper
2. Is it maintained?
- Last commit < 1 year ago?
- Open issues/PRs being addressed?
- Weekly downloads > 100K?
3. What's the size?
- Check bundlephobia.com for bundle impact
- Anything > 50kb needs strong justification
4. What's the vulnerability history?
- npm audit after install
- Check snyk.io/advisor for score
5. Does it have TypeScript types?
- @types/package or built-in types
Rule 5 — Remove Unused Dependencies
# Find unused dependencies
npx depcheck
# Or manually check
cat package.json | grep dependencies -A 100 | grep '"' | \
awk -F'"' '{print $2}' | while read pkg; do
if ! grep -r "from '$pkg'\|require('$pkg')" src/ > /dev/null 2>&1; then
echo "Potentially unused: $pkg"
fi
done
AI instruction: Run depcheck before releases. Unused dependencies increase attack surface and bundle size.
Rule 6 — Lock File Management
# Always commit package-lock.json
# Never edit it manually
# Sync after pulling
npm ci # clean install — uses lock file exactly
# Update lock file after manual package.json changes
npm install
# Verify integrity
npm ci --dry-run
AI instruction: Use npm ci in CI/CD, not npm install. The lock file must always be committed.
Rule 7 — Bundle Size Control
# Analyze bundle
npx webpack-bundle-analyzer build/stats.json
# Or with source-map-explorer
npm install -g source-map-explorer
npm run build
source-map-explorer 'build/static/js/*.js'
// Import only what you need (tree shaking)
// ❌ Imports entire lodash (~70kb)
import _ from 'lodash';
const sorted = _.sortBy(items, 'name');
// ✅ Import specific function (~1kb)
import sortBy from 'lodash/sortBy';
const sorted = sortBy(items, 'name');
// ❌ Entire date-fns
import * as dateFns from 'date-fns';
// ✅ Specific functions
import { format, parseISO } from 'date-fns';
Rule 8 — Dependency Update Strategy
# See what's outdated
npm outdated
# Update a specific package
npm update package-name
# Interactive updates (safer)
npx npm-check-updates -i
# Update all to latest (risky — review changelog first)
npx npm-check-updates -u && npm install
Update policy:
- Security patches → update immediately
- Patch versions → update weekly
- Minor versions → update monthly, test
- Major versions → update quarterly, full regression test
GitHub Actions — Automated Audit
# .github/workflows/security.yml
name: Security Audit
on:
push:
branches: [main]
schedule:
- cron: '0 9 * * 1' # Every Monday
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: '20' }
- run: npm ci
- run: npm audit --audit-level=critical
Companion Script
npx reactforge deps ./
Runs full dependency audit, finds unused packages, and checks for updates.
Quick Reference
npm audit # check vulnerabilities
npm audit fix # fix automatically
npm outdated # see available updates
npx depcheck # find unused dependencies
npm ci # clean install from lock file
npx bundlephobia <package> # check bundle size before installing