About dep-lib-review
A dependency-maintenance skill that guides package updates and vulnerability triage, with procedures for patch, minor, and major upgrades. It is aimed at developers preparing releases or maintaining projects that use pnpm.
Key features
- 01Outdated package inventory
- 02Security vulnerability triage
- 03Patch and minor update batching
- 04One-at-a-time major upgrades
- 05Upgrade validation checklist
Use cases
- 01Monthly dependency maintenance
- 02Reviewing dependencies before a major release
- 03Responding to pnpm audit findings
- 04Planning an ecosystem library upgrade
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ mizchi/ skills --skill dep-lib-reviewAfter installing, type/dep-lib-reviewin Claude Code to confirm it loaded.
Bundled filesREADME.md
Details
From the project READMEDependency Review
Trigger conditions
Run this review when:
- Monthly maintenance cadence
- Before a major release or branch freeze
pnpm auditreports a vulnerability in CI- A major ecosystem library (React, Vite, TypeScript, etc.) drops a new major version
Step 1 — Gather current state
Run in parallel:
# Outdated packages (name, current, wanted, latest)
pnpm outdated 2>/dev/null || true
# Security vulnerabilities (runtime + dev)
pnpm audit --json 2>/dev/null | jq '
.vulnerabilities | to_entries[] |
{ name: .key, severity: .value.severity,
isDirect: .value.isDirect,
via: [.value.via[] | select(type=="object") | .title] }'
# Check if Renovate / Dependabot is configured
ls .github/renovate.json renovate.json .github/dependabot.yml 2>/dev/null || echo "no bot configured"
If a bot (Renovate/Dependabot) is already configured, check its open PRs first — avoid duplicating work.
Step 2 — Triage
Security findings
Do not use CVSS score alone. Apply attack-vector weight:
| CVE type | devDep only | browser SPA | SSR / Edge |
|---|---|---|---|
| RCE | ignore | ignore | P0 |
| XSS via library | ignore | P0 | P0 |
| Prototype Pollution | ignore | P1 (check input path) | P0 |
| ReDoS | ignore | P1 (check user input reach) | P0 |
| Supply chain (postinstall) | P0 | P0 | P0 |
| Path Traversal / SSRF | ignore | ignore | P0 |
# Exclude devDeps to focus on runtime CVEs
# Fallback to plain text if jq parsing fails (pnpm JSON schema varies by version)
pnpm audit --prod --json 2>/dev/null | jq -r '
.vulnerabilities | to_entries[] |
.value.via[] | select(type=="object") |
"\(.severity)\t\(.name)\t\(.title)"' 2>/dev/null | sort -k1 \
|| pnpm audit --prod 2>/dev/null
Version updates — batch strategy
| Update type | Strategy |
|---|---|
| Patch (1.2.3 → 1.2.4) | Batch all in one PR. No changelog read needed. |
| Minor (1.2.x → 1.3.x) | Check changelog for deprecations. Batch non-breaking ones. |
| Major (1.x → 2.x) | One PR per package. Read migration guide. Never batch with other changes. |
Identify the category for each outdated package:
# Categorize outdated packages (deprecated / major / minor / patch)
pnpm outdated --json 2>/dev/null | jq -r '
to_entries[] |
(.value.current // "none") as $cur |
(.value.latest // "none") as $lat |
(.value.dependencyType // "dependencies") as $t |
($cur | split(".")[0]) as $curMaj |
($lat | split(".")[0]) as $latMaj |
(if .value.isDeprecated then "deprecated"
elif $curMaj != $latMaj then "major"
elif ($cur | split(".")[1]) != ($lat | split(".")[1]) then "minor"
else "patch" end) as $category |
"\($category)\t\(.key)\t\($cur) → \($lat)\t\($t)"' | sort
Trend watch (manual check)
Flag any package that matches:
jest→ migrate to vitestaxios→ migrate tofetch/kymoment→ migrate toTemporal/date-fns/ nativeDatelodash→ replace with nativeArray/ObjectAPIswebpack→ migrate to Vitemocha/chai→ migrate to vitest- CJS-only packages in an ESM project (check
exportsfield in theirpackage.json) @types/<pkg>marked deprecated → the base package likely ships its own types now. Verify:cat node_modules/<pkg>/package.json | jq '.types, .typings'. If non-null, remove the@types/<pkg>devDep — zero migration cost.
Step 3 — Execute updates
Patch + safe minor batch
# Update all packages to their "wanted" semver range
pnpm update
# Validate
pnpm typecheck && pnpm test:ci && pnpm lint
If the project has E2E tests:
pnpm test:e2e
Commit as a single PR: chore: update patch/minor dependencies.
Major version update (one package at a time)
# Update single package to latest
pnpm add <package>@latest
# For devDep
pnpm add -D <package>@latest
Then:
- Read the official migration guide / CHANGELOG for breaking changes.
- Check whether an official codemod exists (e.g.
@tailwindcss/upgrade, React codemods). Run it first — it handles ~80-90% of mechanical changes automatically.- After a codemod, audit
package.jsonfor misplacements: some codemods add build-time packages todependenciesinstead ofdevDependencies. Move them if needed. - Codemods may not fully migrate when complex plugins are involved. Check the output log for "could not be automatically migrated" warnings and handle manually.
- After a codemod, audit
- Run
grep -r "deprecated API" src/or use ast-grep for changed APIs. - Fix any breakage.
- Validate:
pnpm typecheck && pnpm test:ci && pnpm lint. - If VRT snapshots exist, regenerate in Linux container after UI-touching upgrades.
- Commit as standalone PR:
chore: upgrade <package> to v<N>.
pnpm troubleshooting for major upgrades
If pnpm install fails after editing package.json:
| Error | Cause | Fix |
|---|---|---|
ERR_PNPM_MISSING_TIME | Stale metadata in pnpm store | pnpm store prune then retry |
ERR_PNPM_NO_MATCHING_VERSION for a package that exists on the registry | Stale lockfile entries conflict with new transitive deps | Delete pnpm-lock.yaml, then pnpm install for a fresh resolution |
After deleting the lockfile, commit the new lockfile alongside the package.json change in the same PR.
Step 4 — Validation checklist
Before marking the PR ready:
-
pnpm typecheckpasses -
pnpm test:cipasses -
pnpm lintpasses -
pnpm buildsucceeds (no bundle-size regression > 5%) - E2E smoke test passes (if applicable)
-
pnpm auditreturns zero high/critical findings (or all remaining are triaged)
Step 5 — Output
Write a brief summary with:
## Dependency review — <YYYY-MM-DD>
### Security
- [FIXED] <package>@<ver>: <CVE title> (was <severity>)
- [IGNORED] <package>: <reason> (devDep-only / browser-only / no user input path)
### Updated
- Patch batch: <N> packages → see commit <sha>
- Major: <package> v<old> → v<new> (standalone PR #<N>)
### Deferred
- <package> v<old> → v<new>: migration effort high, scheduled for <date>
### Trend watch
- <package>: migration recommended → <alternative>
Anti-patterns
- Bundling major upgrades together — one regression makes the entire batch untestable
- Accepting
pnpm audit fix --forceblindly — it can jump major versions silently - Ignoring CVEs without documenting the triage reason
- Updating
@types/*packages separately from their runtime counterpart — always co-update
Related
frontend-review-deps— extended version with scripts for the frontend-review suite (CVE triage + trend-watch data files)upstream-fix-and-pin— when the fix needs to come from patching upstream