audit-and-reduce-dependencies
>-
Works with
Claude CodeCursorCodex CLIGitHub CopilotGemini CLI
--- name: audit-and-reduce-dependencies description: >- license: Apache-2.0 --- # 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**). ## Workflow 0. Hardening gate: run `/check-npm` (read-only). See [check-npm](../check-npm/SKILL.md). 1. Establish the baseline. 2. Remove unused direct dependencies. 3. Deduplicate direct dependency versions in monorepos. 4. Rank direct dependencies by transitive lockfile closure. 5. Use closure data to find low-risk minor/patch upgrades. 6. Use closure data to find trivial dependencies worth inlining. 7. Check e18e recommendations for replacements/removals. 8. Reinstall, verify, and report measured impact. ## Step 0: Hardening gate (`/check-npm`) Run **`/check-npm`** before mutating manifests or lockfiles. - If any check **FAIL**s: report the table and fix snippets; **do not weaken** `pnpm-workspace.yaml`, `.npmrc`, CI install flags, or Renovate age gates during cleanup. - Do not paste full hardening config into this workflow — `/check-npm` owns version thresholds, script policy, git-dep protocols, and min release age. - If the user only asked for hardening (not reduction), stop after `/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. ## Dependency triage 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** - **No new direct dependencies** (including swaps) without explicit user approval. - Prefer **Remove** (inline/native APIs) over **Replace-with-Better** when equivalent. - For **Replace-with-Better**: state why (maintenance, security, smaller tree); prefer actively maintained, widely adopted packages from trusted maintainers. - Respect repo `minimumReleaseAge` / Renovate gates; command-level 72h freshness is a floor, not permission to bypass stricter config. ## pnpm & supply-chain 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: 1. `curl -s https://registry.npmjs.org/<package-name>` 2. Resolve version: pinned `pkg@1.2.3` → that version; range/`latest`/unspecified → `dist-tags.latest` 3. Read `time["<version>"]` 4. If published **less than 72 hours ago** → **stop**. Tell the user package, version, and exact age. Suggest an older known-good pin unless they write **override freshness check**. 5. **`@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. ## Safety rules - Work in small batches so lockfile diffs remain reviewable. - Never trust unused-dependency tools blindly; verify imports, config files, scripts, generated code hooks, framework conventions, plugin names, CLIs, and dynamic imports. - You may write scripting and parsing to verify `package.json` and lockfile dependency accounts. - Treat `peerDependencies`, `optionalDependencies`, package bin usage, test fixtures, and published package manifests as higher risk. - Do not remove or inline dependencies used for security, parsing, crypto, Unicode, URL handling, date/time, i18n, or platform compatibility unless the replacement is proven equivalent. - Do not switch package managers, delete `pnpm-lock.yaml`, or rewrite workspace structure as part of cleanup. - Treat `pnpm dedupe` as potentially behavior-changing; inspect lockfile diffs and run focused verification before keeping the result. - Measure before and after: direct dependency count, lockfile line count or entry count, package count, and estimated `node_modules` size when available. ## Step 1: Baseline Collect: - All `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`). - Direct dependency names by manifest section: `dependencies`, `devDependencies`, `peerDependencies`, `optionalDependencies`. - Existing verification commands from scripts, CI, or repo docs. - **CI spot-check** (`.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. - **Renovate / Dependabot** (if present): note `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. ## Step 2: Remove unused direct dependencies **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: - Search code, configs, package scripts, build tooling, tests, and docs for the package name and known import paths. - Check whether required by a published package manifest, peer contract, plugin loader, CLI command, or dynamic `require`/`import`. - Remove only when no real usage remains. - Run `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. ## Step 3: Deduplicate monorepo direct versions 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. - Use `syncpack list-mismatches` or equivalent for discovery. - Standardize direct ranges when packages can share the same compatible version. - Prefer manifest-level consistency before adding `pnpm.overrides`. - Use `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. ## Step 4: Rank transitive lockfile closure For each important direct dependency, estimate closure: transitive lockfile entries reachable from that dependency. Report both: - **Total closure**: all packages reachable from the dependency. - **Exclusive closure**: packages that disappear if this dependency is removed and are not retained by other direct dependencies. Prefer deterministic measurement: 1. Save baseline lockfile metrics. 2. Temporarily remove one direct dependency from the owning manifest. 3. Run `pnpm install --ignore-scripts` (+ repo flags). 4. Measure lockfile line/entry reduction and package count reduction. 5. Revert the manifest *and* `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. ## Step 5: Find low-risk high-impact upgrades Use closure rankings to target direct dependencies whose newer minor/patch versions reduce transitive dependencies. For each candidate: - Check available non-major versions with `pnpm outdated`. - Review changelog/release notes for dependency tree changes. - Freshness-check the target version, then upgrade one dependency or tight cluster at a time (`pnpm add <pkg>@<version> --ignore-scripts`). - Run `pnpm install --ignore-scripts` (+ repo flags) and compare closure metrics. - Run focused tests and relevant build/typecheck commands. Avoid major upgrades unless the user explicitly accepts the migration risk. ## Step 6: Inline trivial usage Use closure rankings to find direct dependencies with small, obvious usage but large transitive cost. Inline only when all are true: - Usage is tiny and easy to fully characterize. - Equivalent code is shorter or clearer than retaining the dependency. - Behavior is covered by tests or can be covered with small characterization tests. - The dependency is not solving cross-platform, security, parsing, Unicode, locale, or spec-compliance edge cases. Prefer native APIs over new replacement dependencies when the required behavior is simple. ## Step 7: Apply e18e guidance ```bash # Pin @e18e/cli@<version> after freshness check; disable scripts on the dlx install pnpm --config.ignore-scripts=true dlx @e18e/cli@<version> analyze pnpm --config.ignore-scripts=true dlx @e18e/cli@<version> migrate --dry-run ``` 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. ## Reporting Summarize outcomes with measured impact: - `/check-npm` result (PASS/FAIL summary; link fixes if FAIL). - Direct dependencies removed or moved. - Direct versions deduplicated. - Lockfile line/entry reduction. - Estimated package or `node_modules` reduction when available. - High-impact candidates deferred and why (including replacements awaiting approval). - Unsafe protocol / CI / Renovate findings from baseline (if any). - Verification commands run and results. - Supply-chain: versions freshness-checked (or exempted), `--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. ### Reporting format Use for **dependency cleanup findings only** — not GitHub Actions workflow triage. For each finding: - **Evidence**: package name and version/range; manifest path and section; supporting signal (import site, `pnpm why`, knip/depcheck hit, closure measurement, `/check-npm` row, or workflow file + step only for **pnpm install policy**). - **Decision**: one of **Dependency triage** labels. - **Proposed change**: exact manifest/lockfile command or edit. If not applied yet, state that explicitly. - **Rationale**: footprint (exclusive/total closure), supply-chain, maintenance, or verification risk. - **User review required**: tests/build/typecheck to run; peer/plugin/CLI consumers; published-package or dynamic-import risk; approval before **Replace-with-Better** or any new direct dependency. Use one block per package (or per protocol/CI finding), not a single-line summary, when the finding is non-trivial.
More General & Other skills
find-skills
vercel-labs/skills
Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.
1.5M
grill-me
mattpocock/skills
A relentless interview to sharpen a plan or design.
972.7k
grill-with-docs
mattpocock/skills
A relentless interview to sharpen a plan or design, which also creates docs (ADR's and glossary) as we go.
828.8k

