Find which files will hurt the most when they break — dependency risk analysis for any codebase.
Project description
deprisker
Find which files will hurt the most when they break.
deprisker builds a directed dependency graph from your codebase and scores every module by its blast radius — how many other modules would break if it did. It surfaces this as a terminal report, a self-contained interactive HTML visualization, and a structured JSON output for CI pipelines and AI agents.
Why this exists
Every codebase has files that, if incorrectly modified, cascade failures across a disproportionate number of other modules. These high-risk files are not obvious from reading the code. A large file is not necessarily risky. A heavily tested file is not necessarily safe. What actually determines blast radius is structural position in the dependency graph — how many other modules depend on it, whether it bridges otherwise disconnected parts of the system, and whether it participates in circular dependency chains.
deprisker answers the question "which file should I be most careful editing?" before a refactor, release, or code review — in under 10 seconds, with no configuration required.
Features
- Zero configuration — point at a directory, get results
- Multi-language — Python, JavaScript/TypeScript, Go, Rust, Ruby, and Java
- Graph-theoretic scoring — risk is computed from in-degree, betweenness centrality, lines of code, and cycle participation; not heuristics
- Interactive HTML report — force-directed dependency graph, bar chart of top risks, sortable table; all in a single self-contained file with no server required
- CI-ready —
--fail-on-highand--fail-on <score>flags for pipeline integration - MCP server — expose analysis as queryable tools for Claude and other AI agents
- Structured JSON —
--jsonflag for agent pipelines and custom tooling - No LLM required — purely deterministic static analysis
Installation
pip install deprisker
Requires Python 3.9+.
Quick start
# Analyze the current directory
deprisker analyze .
# Analyze a specific project
deprisker analyze ~/projects/myapp
# Top 5 only, skip the HTML report
deprisker analyze . --top 5 --no-html
# Save the HTML report to a custom path
deprisker analyze . --output reports/risk.html
Sample terminal output:
deprisker | analyzing /home/user/myapp
Files scanned : 42
Import edges : 87
Cycles found : 2
High risk : 3
Medium risk : 11
Low risk : 28
-- Top 10 riskiest modules ------------------------------------------
1. [HIGH ] ################.... 74.3 src/auth/middleware.py
2. [HIGH ] ##############...... 68.1 src/db/connection.py
3. [HIGH ] #############....... 62.7 src/core/router.py
4. [MEDIUM] ########............ 41.2 src/utils/logger.py
5. [MEDIUM] #######............. 37.8 src/models/user.py
HTML report saved -> /home/user/myapp/deprisker_report.html
CLI reference
deprisker analyze [PATH] [OPTIONS]
PATH defaults to . if not provided.
| Flag | Short | Description |
|---|---|---|
--output PATH |
-o |
Output path for the HTML report (default: deprisker_report.html) |
--top N |
-t |
Number of top-risk files to print (default: 10) |
--json |
-j |
Print JSON to stdout, suppress all other output |
--no-html |
Skip writing the HTML report | |
--threshold FLOAT |
Report only files with score ≥ threshold | |
--fail-on-high |
Exit code 1 if any HIGH risk modules exist | |
--fail-on FLOAT |
Exit code 1 if any module score ≥ this value | |
--include TEXT |
Comma-separated path prefixes to include only | |
--exclude TEXT |
Comma-separated path prefixes to exclude | |
--version |
-v |
Print version and exit |
Exit codes: 0 = success · 1 = threshold violated · 2 = input error · 3 = output error · 4 = invalid arguments
HTML report
The generated report is a single .html file that works offline. It contains:
- Force-directed graph — nodes sized by risk score, colored by risk level (red/amber/green), with zoom, pan, drag, and hover tooltips showing full risk breakdown
- Bar chart — top 10 modules ranked by score
- Sortable table — all modules with score, risk level, and dependent count; clicking a row highlights the node in the graph
No web server required. The file can be committed to the repo, shared with the team, or attached to a pull request.
Python API
from deprisker import analyze, render_html
report = analyze("./my-project")
# Summary statistics
print(report.summary)
# {'total_files': 42, 'total_edges': 87, 'cyclic_dependencies': 2,
# 'high_risk_count': 3, 'medium_risk_count': 11, 'low_risk_count': 28, ...}
# Top riskiest files
for path, score in report.top_risks[:5]:
node = report.nodes[path]
print(f"{score:.1f} [{node.risk_level}] {path}")
print(f" dependents={node.risk_factors['dependents']}, "
f"in_cycle={node.risk_factors['in_cycle']}")
# All circular dependency chains
for cycle in report.cycles:
print(" -> ".join(cycle) + " -> ...")
# Write the HTML report
out = render_html(report, "risk_report.html")
print(f"Report saved to {out}")
CI integration
Fail a build if any HIGH risk module is present in the changed files:
# .github/workflows/risk-check.yml
- name: Install deprisker
run: pip install deprisker
- name: Check dependency risk
run: deprisker analyze . --no-html --fail-on-high
Fail if any module score exceeds a custom threshold:
deprisker analyze . --no-html --fail-on 70
Use JSON output for custom logic:
import json, subprocess, sys
result = subprocess.run(
["deprisker", "analyze", ".", "--json"],
capture_output=True, text=True
)
data = json.loads(result.stdout)
high_risk = [m for m in data["modules"] if m["risk_level"] == "HIGH"]
if high_risk:
print(f"ERROR: {len(high_risk)} HIGH risk modules")
sys.exit(1)
MCP server
deprisker exposes its analysis as an MCP server, allowing Claude and other AI agents to query dependency risk data without running the CLI.
deprisker mcp # stdio transport (for Claude Desktop)
deprisker mcp --transport http --port 8080 # HTTP transport
Add to claude_desktop_config.json:
{
"mcpServers": {
"deprisker": {
"command": "deprisker",
"args": ["mcp"]
}
}
}
Available tools:
| Tool | Description |
|---|---|
analyze_project |
Analyze a directory, cache the result |
get_top_risks |
Return the N riskiest modules, with optional level/language filter |
get_module_risk |
Full risk breakdown for a specific file |
get_dependents |
Direct and transitive dependents of a module |
get_cycles |
All circular dependency chains |
check_blast_radius |
Given a list of files (e.g. a PR diff), compute total affected modules |
generate_report |
Write an HTML report to disk |
Risk scoring
Each module is scored 0–100 using four weighted graph metrics:
| Metric | Weight | What it measures |
|---|---|---|
| In-degree | 35 | How many other modules import this one — the primary blast radius signal |
| Betweenness centrality | 30 | How often this module is the bridge between others — breaking it disconnects the graph |
| Lines of code | 15 | Surface area for bugs; larger files are harder to change safely |
| Cycle participation | 20 | Flat penalty for being in a circular dependency — changes ripple unpredictably |
Risk levels:
HIGH— score ≥ 60. A bug here cascades widely.MEDIUM— score 30–59. Changes warrant extra review.LOW— score < 30. Relatively safe to modify independently.
All weights and thresholds are configurable via the Python API:
from deprisker import analyze
from deprisker.config import Config
cfg = Config(
weight_in_degree=40,
weight_betweenness=25,
weight_loc=15,
weight_cycle=20,
high_threshold=65.0,
)
report = analyze(".", config=cfg)
Language support
| Language | Extensions | Import strategy |
|---|---|---|
| Python | .py |
AST-based (ast module) |
| JavaScript / TypeScript | .js .ts .jsx .tsx .mjs .cjs |
Regex — ESM imports and require() |
| Go | .go |
Regex — single and block imports; go.mod-aware |
| Rust | .rs |
Regex — use crate::, use super::, mod name; |
| Ruby | .rb |
Regex — require_relative and require |
| Java | .java |
Regex — fully-qualified imports; base package auto-detected |
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file deprisker-0.1.0.tar.gz.
File metadata
- Download URL: deprisker-0.1.0.tar.gz
- Upload date:
- Size: 42.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
02d4eef188726dacac37b44e9255f8c7205ae9b64a3bc4bf679f631bf8ec3b6c
|
|
| MD5 |
229eb820fe9f188965245928b35eacff
|
|
| BLAKE2b-256 |
abe42942be88e5a7c3e91b4f4ad9ff20ebb2a90ee20d0f49f3330c39e49596cb
|
File details
Details for the file deprisker-0.1.0-py3-none-any.whl.
File metadata
- Download URL: deprisker-0.1.0-py3-none-any.whl
- Upload date:
- Size: 21.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
41da4f561d30ba4cf34f4ef1622a507d78f27c3503b3473ea054f600a3167f7c
|
|
| MD5 |
6d452f7e5c812ac445e50772ab758446
|
|
| BLAKE2b-256 |
5b66d2c2855b62f3e49a18631a9de5f3eb24230b4067d1d3a28e9aa185630fe9
|