Sbp dependency audit
Use when conducting a security review, reducing dependency surface, or when dependencies may pose supply-chain, bloat, or maintainability risks.From its SKILL.md
npx -y skills add schubergphilis/agents.md --skill sbp-dependency-auditAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 8 stars8 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
7.1 KB, as published. Nobody here has run it
Dependency Audit
Audit project dependencies for bloat, risk, and supply-chain concerns. The goal is a clear picture of what you depend on, why, and whether each dependency is worth the risk it carries.
Work incrementally — one category at a time. Do not try to fix everything at once.
Step 1: Discovery
Build a complete inventory of dependencies and actual usage.
List all direct dependencies:
- Python: parse
pyproject.toml,requirements.txt,setup.py,setup.cfg. - JavaScript/TypeScript: parse
package.json(bothdependenciesanddevDependencies). - Go: parse
go.mod. - Note the declared version constraints (pinned, range, latest).
Identify what is actually imported:
- Search the codebase for actual import statements and usage of each dependency.
- Flag dependencies that are declared but never imported — these are removal candidates.
- Note which specific functions or classes are used from each dependency. A project that imports one function from a 50,000-line library is a candidate for inlining.
Map transitive dependencies:
- Use the lockfile (
uv.lock,package-lock.json,go.sum) to count transitive dependencies. - Each transitive dependency is an attack surface you did not choose. High transitive counts deserve scrutiny.
Step 2: Classification
Classify each direct dependency into one of five categories:
Keep
Large, well-maintained, complex libraries where writing your own would be foolish.
Criteria: actively maintained (commits in last 6 months), multiple maintainers, solves a genuinely hard problem (HTTP server, cryptography, database driver, ML framework), widely used and battle-tested.
Inline
Tiny packages that do one simple thing in under 100 lines of code.
Criteria: the functionality is trivial to implement, the package has few or no updates, and depending on it adds supply-chain risk disproportionate to its value. Copy the implementation (respecting the license), add a comment noting the origin, and remove the dependency.
Examples: left-pad-style packages, simple string utilities, single-function math helpers.
Replace with native
Packages that provide functionality now available in the language's standard library or in a dependency you already have.
Criteria: the functionality exists natively in the current language version or in a library already in your dependency tree. Common cases: backport packages for features now in the stdlib, polyfill packages for APIs now widely available.
Vendor
Narrow-purpose, stable packages where you want to lock the exact code but the package is too complex to inline.
Criteria: the package is stable (no updates needed), you use it for a specific purpose, and you want to decouple from the package registry. Copy the package into a vendor/ or 3rdparty/ directory, preserving its license.
Remove
Packages that are not imported anywhere, or that are imported but the functionality is unused (dead code paths).
Criteria: no import found in the codebase, or the import exists but the code path is never reached. Remove the dependency and run the test suite to confirm nothing breaks.
Step 3: Supply-chain risk assessment
For each dependency classified as "keep," evaluate supply-chain risk:
Maintenance status:
- When was the last release? Last commit?
- How many maintainers have commit access? (Single-maintainer packages are higher risk)
- Is there a bus factor problem?
Known vulnerabilities:
- Check against vulnerability databases (OSV, GitHub Advisory Database, Snyk).
- Note any unpatched CVEs, especially in dependencies that handle untrusted input (parsers, serializers, network libraries).
Trust indicators:
- Is the package from a known organization or verified publisher?
- Does the package use 2FA for publishing?
- Has the package ever been involved in a supply-chain incident?
Attack surface analysis for mission-critical systems:
- Does this dependency have install-time hooks (setup.py with custom install commands, postinstall scripts)? These execute arbitrary code during
pip installornpm install. - Does this dependency download additional code at runtime?
- Does this dependency require network access to function?
- Could a compromised version of this dependency access secrets, credentials, or customer data in your environment?
Flag any dependency that is: unmaintained (no updates in 12+ months), single-maintainer, has known vulnerabilities, or has install-time code execution.
Step 4: Action plan
Produce a prioritized list of actions. Work through these one category at a time, running the full test suite after each change.
Priority 1 — Remove (lowest effort, immediate risk reduction):
- Remove unused dependencies. Run tests. Commit.
Priority 2 — Replace with native (low effort, reduces surface area):
- Replace backport/polyfill packages with native equivalents. Run tests. Commit.
Priority 3 — Inline (moderate effort, meaningful risk reduction):
- For each inline candidate: copy the relevant code, respect the license, add an origin comment, remove the dependency. Run tests. Commit.
Priority 4 — Vendor (moderate effort, supply-chain protection):
- For each vendor candidate: copy the package, preserve the license, update import paths. Run tests. Commit.
Priority 5 — Address vulnerabilities (effort varies):
- For each vulnerability: update to a patched version if available, or evaluate whether the vulnerability is exploitable in your usage.
Priority 6 — Monitor (ongoing):
- Set up automated vulnerability scanning (Dependabot, Renovate, Snyk).
- Review new dependencies at PR time — every new dependency is a new trust decision.
Output
Produce two artifacts:
Summary table
| Package | Version | Category | Risk | Action | Effort | Notes |
|---|---|---|---|---|---|---|
| requests | 2.31.0 | Keep | Low | None | - | Well-maintained, widely used |
| left-pad | 1.0.0 | Inline | Medium | Copy 3-line implementation | 15 min | Single maintainer, trivial function |
| typing-extensions | 4.8.0 | Replace | Low | Remove (Python 3.11+) | 5 min | Backport no longer needed |
Detailed recommendations
For each action item, provide:
- What to do (specific steps or code snippet).
- What to watch out for (license implications, breaking changes).
- How to verify (which tests to run, what to check).
Important reminders
- Always respect licenses. When inlining or vendoring, include the original license and attribution.
- Always run the full test suite after each change. Do not batch removals — one at a time, verified.
- Do not remove devDependencies used in CI. Check CI pipeline configuration, not just application code.
- Some "unused" imports are used dynamically. Check for plugin systems, lazy imports, and conditional imports before removing.
- Coordinate with the team. Dependency changes affect everyone. Communicate before making sweeping changes.