dep-audit
A CLI tool that identifies unnecessary dependencies in software projects. It answers the question existing tools don't ask: "which of your dependencies can you remove because the language itself now provides that functionality, the package is deprecated, or you never actually import it?"
What it finds
| Category | Examples |
|---|---|
| Stdlib backports | pytz → zoneinfo, tomli → tomllib, lazy-static → std::sync::LazyLock, go.uber.org/atomic → sync/atomic |
| Zombie shims | six, future — Python 2/3 compat layers; winapi → windows-sys |
| Deprecated packages | pycrypto → pycryptodome, failure → thiserror + anyhow, request (npm), github.com/dgrijalva/jwt-go → golang-jwt/jwt |
| Micro-utilities | is-odd, is-even, left-pad — single expressions in native code |
| Unused dependencies | Packages in your lockfile that are never imported in your source code |
Supports Python, npm/Node.js, Cargo/Rust, and Go.
Install
# Run without installing (recommended for one-off scans)
uvx dep-audit scan .
# Install globally with pipx
pipx install dep-audit
# Install in a project
uv add --dev dep-audit
pip install dep-audit
Requires Python 3.11+. Zero runtime dependencies.
Quick start
# Scan the current directory
dep-audit scan .
# Scan a specific project
dep-audit scan /path/to/my-project
# Scan a GitHub repo (no clone needed)
dep-audit scan fastapi/fastapi
dep-audit scan django/django --ref stable/5.1.x
# Check a single package
dep-audit check pytz
dep-audit check lazy-static --ecosystem cargo
dep-audit check left-pad --ecosystem npm --offline
dep-audit check github.com/pkg/errors --ecosystem go
Ecosystems
| Ecosystem | Detection | Lockfiles parsed |
|---|---|---|
| Python | pyproject.toml, requirements.txt, setup.py |
uv.lock, poetry.lock, pyproject.toml, requirements.txt |
| npm | package.json |
package-lock.json, yarn.lock, pnpm-lock.yaml, package.json |
| Cargo | Cargo.toml |
Cargo.lock, Cargo.toml |
| Go | go.mod |
go.mod |
dep-audit detects the ecosystem automatically. In multi-language repos it scans each detected ecosystem separately.
Commands
scan — scan a project
dep-audit scan [path] [options]
| Option | Description |
|---|---|
path |
Project root or owner/repo GitHub shorthand (default: .) |
--format terminal|json|sarif |
Output format (default: terminal) |
--offline |
Skip deps.dev API calls (faster, no network needed) |
--target-version 3.11 |
Override the language version for stdlib detection |
--ecosystem python |
Force a specific ecosystem instead of auto-detecting |
--include-dev |
Include dev/test dependencies in the scan |
--exit-code |
Exit with code 1 if any issues are found (for CI) |
--min-confidence 0.8 |
With --exit-code: only fail on findings at or above this threshold (0.0–1.0) |
--ignore PKG |
Suppress a package entirely — hidden from report (repeatable) |
--known PKG |
Mark a finding as intentional — still shown, won't trigger --exit-code (repeatable) |
--ref main |
Git ref for remote repos (branch, tag, or commit SHA) |
check — look up a single package
dep-audit check <package> [--ecosystem python] [--offline]
Shows the package classification, what it can be replaced with, and live data from deps.dev (deprecated status, open advisories). Use --offline to skip the network call.
db — manage the junk database
dep-audit db list python # List all entries grouped by type
dep-audit db list cargo # List Cargo entries
dep-audit db show pytz # Show entry for one package
# Discover new candidate entries from a project
dep-audit db export --discovered .
dep-audit db export --discovered fastapi/fastapi
cache — manage the API cache
dep-audit cache clear # Delete ~/.cache/dep-audit/
Output formats
Terminal (default)
Results are grouped into four sections, most actionable first:
=== dep-audit: my-app (Python 3.12) ===
REMOVE — unused dependencies (zero effort):
six ············································ not imported anywhere in project
just delete from dependency list
REPLACE — stdlib alternatives available:
pytz ··········································· stdlib_backport → datetime.zoneinfo (since 3.9)
2 imports in src/utils.py:5
SIMPLIFY — micro-utilities (inline replacements):
is-odd ········································· micro_utility → x % 2 !== 0
3 imports across 2 files
DEPRECATED:
pycrypto ······································· deprecated → pycryptodome
SUMMARY
4 unnecessary packages found
18 total production dependencies scanned
1 zero-effort removal
1 stdlib replacement
1 micro-utility to inline
1 deprecated
JSON
dep-audit scan . --format json | jq '.flagged[]'
Schema:
{
"project": "my-app",
"ecosystem": "python",
"target_version": "3.12",
"scan_mode": "local",
"scanned_at": "2026-03-07T12:00:00+00:00",
"production_deps": 18,
"flagged": [
{
"name": "pytz",
"version": "2024.1",
"classification": "stdlib_backport",
"confidence": 0.95,
"is_direct": true,
"imports": 2,
"replacement": "datetime.zoneinfo",
"stdlib_since": "3.9",
"files": [{"path": "src/utils.py", "line": 5}]
}
],
"summary": {
"zero_effort_removals": 1,
"stdlib_replacements": 1,
"micro_utilities": 0,
"deprecated": 0,
"total_transitive_freed": 2
}
}
SARIF (GitHub Code Scanning)
dep-audit scan . --format sarif > dep-audit.sarif
SARIF 2.1.0 output for GitHub Code Scanning and any tool that consumes SARIF. Findings map to rule IDs:
| Rule | Classification | Default level |
|---|---|---|
| DEP001 | stdlib_backport |
warning |
| DEP002 | zombie_shim |
warning |
| DEP003 | deprecated |
error |
| DEP004 | micro_utility |
note |
Low-confidence findings (below 0.7) are downgraded to note.
Configuration
dep-audit reads config from the first file it finds, in priority order:
.dep-audit.toml— standalone config, works for any ecosystempyproject.toml—[tool.dep-audit]section, Python projects only
CLI flags always override config values.
.dep-audit.toml (or [tool.dep-audit] in pyproject.toml):
ignore = ["lodash", "uuid"] # hide these packages from the report entirely
known = ["typing-extensions"] # show findings but don't fail --exit-code
target-version = "3.11" # language version for stdlib checks
ecosystem = "python" # force a specific ecosystem
offline = true # always skip deps.dev API
exit-code = true # always use exit code mode
min-confidence = 0.8 # only fail CI on findings >= this confidence
target-version is auto-detected from the project manifest:
| Ecosystem | Detected from | Example |
|---|---|---|
| Python | requires-python in pyproject.toml |
>=3.11 → 3.11 |
| Rust | package.rust-version in Cargo.toml |
1.70 |
| npm | engines.node in package.json |
>=18.0.0 → 18.0 |
| Go | go directive in go.mod |
go 1.21 → 1.21 |
If the field is absent, dep-audit falls back to a safe default (Python: running interpreter, Rust: 1.80, Node: 22, Go: 1.21).
Inline ignores
Suppress a single package by adding a comment inline. Supported in requirements.txt:
requests==2.31.0
six==1.16.0 # dep-audit: ignore
Suppressing findings
Three ways to stop a finding from blocking CI, each with different intent:
ignore — hide completely
The package disappears from the report entirely. Use this for genuine false positives.
[tool.dep-audit]
ignore = ["typing-extensions"] # needed for runtime type hints on 3.10
dep-audit scan . --ignore typing-extensions
known — acknowledge, don't block
The package still appears in the report but won't cause --exit-code to return 1. Use this for deliberate decisions — packages you know are flagged and have chosen to keep ("won't fix").
[tool.dep-audit]
known = ["six"] # legacy code, migration planned for Q3
dep-audit scan . --known six
A note appears in stderr when known findings are present:
1 known finding(s) suppressed from --exit-code: six
--min-confidence — raise the threshold
Only fail CI on findings above a confidence threshold. Useful during migrations where you want to enforce clear-cut findings (confidence 1.0) but tolerate uncertain ones.
dep-audit scan . --exit-code --min-confidence 0.9
CI integration
GitHub Actions
name: dep-audit
on: [push, pull_request]
jobs:
dep-audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Scan dependencies
run: uvx dep-audit scan . --exit-code --offline
GitHub Actions with Code Scanning (SARIF)
Upload findings as inline annotations on pull requests:
name: dep-audit
on: [push, pull_request]
jobs:
dep-audit:
runs-on: ubuntu-latest
permissions:
security-events: write
steps:
- uses: actions/checkout@v4
- name: Scan dependencies
run: uvx dep-audit scan . --format sarif --offline > dep-audit.sarif
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: dep-audit.sarif
GitLab CI
dep-audit:
image: python:3.12-slim
script:
- pip install dep-audit
- dep-audit scan . --exit-code --offline
Jenkins
stage('dep-audit') {
sh 'uvx dep-audit scan . --exit-code --offline'
}
pre-commit
dep-audit is a pre-commit plugin. Add it to .pre-commit-config.yaml:
repos:
- repo: https://github.com/zfoq/dep-audit
rev: 0.5.0
hooks:
- id: dep-audit
The hook only runs when lockfiles or manifests change, so it doesn't slow down unrelated commits.
pre-commit install
pre-commit run dep-audit --all-files # verify it works
To pass extra flags:
hooks:
- id: dep-audit
args: [scan, ., --exit-code, --offline, --include-dev]
Offline vs online mode
By default dep-audit calls deps.dev to:
- Resolve transitive dependencies — when you only have
requirements.txtorpyproject.toml(no lockfile), it queries deps.dev to discover what each direct dep pulls in transitively. - Detect live deprecations — checks whether packages have been marked deprecated upstream, beyond what's in dep-audit's own database.
If your project has a full lockfile (uv.lock, package-lock.json, Cargo.lock), transitive deps are already in the file and the network resolution is skipped automatically. --offline only disables the live deprecation check.
Use --offline in CI/pre-commit for speed and determinism.
Remote scanning
Scan any public GitHub repo without cloning it:
dep-audit scan fastapi/fastapi
dep-audit scan https://github.com/pallets/flask
dep-audit scan django/django --ref stable/5.1.x
dep-audit scan expressjs/express --ecosystem npm --format json
Import usage analysis is skipped for remote scans since source code is not downloaded. Transitive dependency chains are still traced.
Cargo workspaces
For Cargo workspace repos, point dep-audit at a specific workspace member instead of the workspace root to get accurate direct-dependency attribution:
# Workspace root — scans all deps but can't tell which are direct for each crate
dep-audit scan .
# Workspace member — accurate results for that specific crate
dep-audit scan ./crates/my-crate
dep-audit scan ./tokio # inside a tokio-style workspace
Go modules
Go module paths contain slashes (e.g. github.com/pkg/errors). Use the full module path when checking a single package:
dep-audit check github.com/pkg/errors --ecosystem go
dep-audit check github.com/dgrijalva/jwt-go --ecosystem go
dep-audit db show github.com/gogo/protobuf --ecosystem go
For multi-module repos, point dep-audit at the directory that contains the relevant go.mod:
dep-audit scan . # top-level go.mod
dep-audit scan ./cmd/myservice # sub-module with its own go.mod
Import scanning walks all .go files under the project root, excluding vendor/ and testdata/ automatically.
Junk database
The database covers 141 packages across all ecosystems (Python: 43, npm: 57, Cargo: 21, Go: 20). Each entry is a TOML file in src/dep_audit/db/{ecosystem}/:
name = "pytz"
ecosystem = "python"
type = "stdlib_backport" # stdlib_backport | zombie_shim | deprecated | micro_utility
replacement = "datetime.zoneinfo"
stdlib_since = "3.9"
confidence = 0.95
flags = ["stdlib_backport: zoneinfo available since Python 3.9"]
validated = 2026-01-15
Contributing entries
Found a package that should be flagged?
# Preview auto-generated stubs from a project scan
dep-audit db export --discovered .
dep-audit db export --discovered fastapi/fastapi
Review the output, fill in the details, and open a PR with the new .toml file.
Development
git clone https://github.com/zfoq/dep-audit
cd dep-audit
uv sync --group dev
# Run tests
uv run pytest
# Lint and type-check
uv run ruff check src/ tests/
uv run mypy src/
# Try it on itself
uv run dep-audit scan . --offline
License
MIT
Metadata
Release files for dep-audit 0.5.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| dep_audit-0.5.0.tar.gz | 50.2 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| dep_audit-0.5.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 155.1 kB
Release files / dep_audit-0.5.0.tar.gz
| Download URL | dep_audit-0.5.0.tar.gz |
|---|---|
| Size | 50.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d556fb976d471bbe1a44f211da4fcf49816ca6c2bba4d46c54e4eb423a91691e
|
|
BLAKE2b-256 checksum How to use checksums |
20da9273354ed9786521b2c1093cbfe1a963b14080b0b07f2ee4e56108a1bb4a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 7, 2026.
Transparency logRelease files / dep_audit-0.5.0-py3-none-any.whl
| Download URL | dep_audit-0.5.0-py3-none-any.whl |
|---|---|
| Size | 104.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
12ce96e0e9d0f0c2c1600ee0b64937be74a6f92ed2552f4e0e60a9239abfe41e
|
|
BLAKE2b-256 checksum How to use checksums |
d62859049cb145538d333591174001cf9744b5f0fd54f5e787356dcfc15da03c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 7, 2026.
Transparency logSecurity for dep-audit 0.5.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for dep_audit-0.5.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 7, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.