# Dependency Governance

> Manage npm dependencies safely — vulnerability remediation, version pinning, audit policies, bundle size control, and dependency lifecycle. Works in any Node.js project.

- Skill: `kirti/dependency-governance-2` (Agent Skill)
- Install (CLI): `npx skillmds@latest add kirti/dependency-governance-2`
- Raw SKILL.md: https://api.skillmd.com/api/skills/kirti/dependency-governance-2/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: kirti (https://skillmd.com/u/kirti)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/kirti/dependency-governance-2

---


# 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

```bash
# 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.
```

```bash
# 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

```json
// 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

```bash
# 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

```bash
# 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

```bash
# 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'
```

```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

```bash
# 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

```yaml
# .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
```bash
npx reactforge deps ./
```
Runs full dependency audit, finds unused packages, and checks for updates.

---

## Quick Reference
```bash
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
```

