npx skills add ...
npx skills add grafana/skills --skill audit-and-reduce-dependencies
Reduces JavaScript dependency footprint with pnpm while preserving lockfile, workspace layout, and dependency range style. Runs /check-npm first, then removes unused deps, dedupes versions, ranks transitive closure, and reports Keep/Replace/Remove triage. Use when cleaning up pnpm dependencies, reducing lockfile size, or shrinking node_modules in Grafana plugins; not for Go modules or full GitHub Actions workflow audits.
npx skills add grafana/skills --skill audit-and-reduce-dependencies
Reduce JavaScript dependency footprint. Use pnpm only. Preserve the lockfile, workspace layout, and dependency range style unless there is a concrete reason to change them.
For GitHub Actions workflow triage (action choice, permissions, pinning), use a dedicated workflow audit — not the reporting format below (workflow file + step only when the finding is pnpm install policy).
/check-npm (read-only). See check-npm./check-npm)Run /check-npm before mutating manifests or lockfiles.
pnpm-workspace.yaml, .npmrc, CI install flags, or Renovate age gates during cleanup./check-npm owns version thresholds, script policy, git-dep protocols, and min release age./check-npm unless they also want cleanup.pnpm 11+: script and release-age policy live in pnpm-workspace.yaml, not .npmrc or package.json#pnpm (pnpm 11 no longer reads the package.json#pnpm field). Verify each key against the installed pnpm major before suggesting config. Never add unsupported keys. Do not lower an existing minimumReleaseAge (or org equivalent) during cleanup.
For each non-trivial direct dependency (especially after Steps 4–7), assign one label:
| Label | Meaning |
|---|---|
| Keep | Required; worthwhile transitive cost; well maintained. |
| Replace-with-Better | Required; better-maintained or safer alternative exists. |
| Replace-with-Internal | Required; external risk warrants internal implementation. |
| Remove | Can drop or inline (Step 6). |
| Needs-user-review | Ambiguous usage, policy tradeoff, or change needing human verification. |
Replacements and new direct deps
minimumReleaseAge / Renovate gates; command-level 72h freshness is a floor, not permission to bypass stricter config.Confirm the repo uses pnpm: pnpm-lock.yaml, pnpm-workspace.yaml, and/or packageManager / devEngines.packageManager.name set to pnpm in root package.json. If not on pnpm, stop — do not migrate package managers as part of cleanup.
Respect repo install policy when present (e.g. pnpm install --frozen-lockfile --ignore-scripts).
| Action | Command |
|---|---|
| Install/update lockfile | pnpm install --ignore-scripts (+ repo flags, e.g. --frozen-lockfile) |
| Remove direct dependency | pnpm remove <pkg> --ignore-scripts |
| Add/update direct dependency | pnpm add <pkg>@<version> --ignore-scripts |
| Explain dependency | pnpm why <pkg> |
| Dedupe lockfile | pnpm dedupe (then pnpm install --ignore-scripts if lockfile changed) |
| Outdated / version info | pnpm outdated <pkg> |
| One-off tools | pnpm --config.ignore-scripts=true dlx <pkg>@<version> <args...> (pin version; prefer pnpm exec when in lockfile) |
Lifecycle scripts: Always --ignore-scripts on pnpm install, pnpm add, and pnpm remove unless the user explicitly writes allow scripts in the same message (state which scripts would run and the risk). For pnpm dlx, dlx does not accept --ignore-scripts directly — use pnpm --config.ignore-scripts=true dlx (flags after dlx are forwarded to the executed binary). If a dependency legitimately needs a build script (native modules, etc.), finish without scripts, then ask whether to run a specific manual rebuild (e.g. pnpm rebuild <pkg>).
Freshness check (≥ 72 hours) — required before any command that adds or upgrades a named package version (pnpm add, pnpm dlx with new/upgraded direct version). Not required for plain pnpm install / pnpm remove with no new package argument.
For each directly named package:
curl -s https://registry.npmjs.org/<package-name>pkg@1.2.3 → that version; range/latest/unspecified → dist-tags.latesttime["<version>"]@grafana/* scoped packages are exempt from the freshness check; --ignore-scripts still applies.After a failed freshness check, do not substitute a different version without user approval.
package.json and lockfile dependency accounts.peerDependencies, optionalDependencies, package bin usage, test fixtures, and published package manifests as higher risk.pnpm-lock.yaml, or rewrite workspace structure as part of cleanup.pnpm dedupe as potentially behavior-changing; inspect lockfile diffs and run focused verification before keeping the result.node_modules size when available.Collect:
package.json files and workspace boundaries (pnpm-workspace.yaml).pnpm-lock.yaml, pnpm-workspace.yaml security settings (minimumReleaseAge, strictDepBuilds, blockExoticSubdeps, allowBuilds), and install policy in .npmrc / CI flags (e.g. --frozen-lockfile, --ignore-scripts).dependencies, devDependencies, peerDependencies, optionalDependencies..github/workflows or equivalent): installs should use pnpm install --frozen-lockfile and script blocking consistent with workspace config. Flag workflows that regenerate lockfiles on every run.minimumReleaseAge for npm packages; do not reduce it during cleanup.Record baseline metrics: git status --short, wc -l pnpm-lock.yaml. If node_modules is installed, estimate footprint with platform-appropriate tools. Lockfile reductions are the primary metric — do not depend on node_modules being present.
Unsafe direct dependency protocols — scan all workspace package.json dependency sections. Flag values that are not: semver range, workspace:, patch:, or npm: alias to semver. Flag git: / github: / tarball URLs / user/repo shorthand / file: / link: / exec: / etc. (same allow-list as /check-npm). Do not remove flagged entries silently; report for a separate hardening PR unless the user asked to fix them.
Use a static analyzer as a starting point, not as proof (knip, depcheck, or repo-native tooling). Run with pinned pnpm --config.ignore-scripts=true dlx <tool>@<version> <args...> when not installed (freshness-check the pin first).
For each candidate:
require/import.pnpm install --ignore-scripts (+ repo flags) and focused verification.If usage is only in a script or config, consider moving between dependencies and devDependencies instead of removing.
Look for the same direct dependency declared with multiple versions/ranges across package manifests. Use existing policy first: exact pins, caret ranges, catalog/protocol usage, workspace protocol, or central constraints.
syncpack list-mismatches or equivalent for discovery.pnpm.overrides.pnpm.overrides only for transitive convergence or security fixes, and document why.After deduping, run pnpm install --ignore-scripts (+ repo flags) and inspect manifest and lockfile diffs. Then consider pnpm dedupe — apply carefully; may change transitive resolution.
For each important direct dependency, estimate closure: transitive lockfile entries reachable from that dependency.
Report both:
Prefer deterministic measurement:
pnpm install --ignore-scripts (+ repo flags).pnpm-lock.yaml (e.g., git checkout -- <manifest> pnpm-lock.yaml) before measuring the next dependency.Use pnpm why <pkg> for large transitive packages. Rank by impact and risk, not just raw size.
Use closure rankings to target direct dependencies whose newer minor/patch versions reduce transitive dependencies.
For each candidate:
pnpm outdated.pnpm add <pkg>@<version> --ignore-scripts).pnpm install --ignore-scripts (+ repo flags) and compare closure metrics.Avoid major upgrades unless the user explicitly accepts the migration risk.
Use closure rankings to find direct dependencies with small, obvious usage but large transitive cost.
Inline only when all are true:
Prefer native APIs over new replacement dependencies when the required behavior is simple.
Also check https://e18e.dev/docs/replacements/. Treat recommendations as candidates, not mandates; verify bundle/runtime behavior and run tests. Map e18e swaps to Replace-with-Better only after user approval.
Summarize outcomes with measured impact:
/check-npm result (PASS/FAIL summary; link fixes if FAIL).node_modules reduction when available.--ignore-scripts on all installs/adds, --config.ignore-scripts=true on pnpm dlx.Call out risk explicitly when a removal depends on static analysis rather than runtime coverage.
Use for dependency cleanup findings only — not GitHub Actions workflow triage.
For each finding:
pnpm why, knip/depcheck hit, closure measurement, /check-npm row, or workflow file + step only for pnpm install policy).Use one block per package (or per protocol/CI finding), not a single-line summary, when the finding is non-trivial.