Static analysis CLI for TypeScript, JavaScript, Go, Python, Rust, and Java that computes Local Risk Score (LRS)
Project description
Hotspots
Website: https://hotspots.dev | Docs: https://docs.hotspots.dev | Crates.io:
Install: brew install Stephen-Collins-tech/tap/hotspots | npm install -g @stephencollinstech/hotspots | pip install hotspots-cli | cargo install hotspots-cli
Find the code that's actually causing problems.
Your codebase has thousands of functions. Some are messy but never break. Others are complex AND change constantly — those are your hotspots, the 20% of code causing 80% of your bugs, incidents, and slowdowns.
Install
brew install Stephen-Collins-tech/tap/hotspots # macOS
npm install -g @stephencollinstech/hotspots # any platform
pip install hotspots-cli # any platform
cargo install hotspots-cli # Rust toolchain
curl -fsSL https://raw.githubusercontent.com/Stephen-Collins-tech/hotspots/main/install.sh | sh # Linux
Windows: download the binary from GitHub Releases.
Verify: hotspots --version
GitHub Action:
- uses: Stephen-Collins-tech/hotspots/action@v1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
Quick Start
# Find your hotspots
hotspots analyze src/
# Critical (LRS ≥ 9.0):
# processPlanUpgrade src/api/billing.ts:142 LRS 12.4 CC 15 ND 4 FO 8 NS 3
#
# High (6.0 ≤ LRS < 9.0):
# validateSession src/auth/session.ts:67 LRS 9.8 CC 11 ND 3 FO 7 NS 2
Critical = refactor now. High = refactor next time you touch it. Moderate = block increases. Low = leave it alone.
Common commands
# Per-function explanations with refactoring advice
hotspots analyze . --mode snapshot --format text --explain --top 10
# Block complexity regressions in CI
hotspots analyze src/ --mode delta --policy
# Compare any two git refs
hotspots diff main HEAD --top 10 --policy
# Interactive HTML report
hotspots analyze src/ --mode snapshot --format html
# JSON for tooling/AI
hotspots analyze src/ --format json
# Track trends over time
hotspots trends .
# Train a repo-specific ranker from your bug history
hotspots train . --blame --eval
How It Works
Hotspots computes a Local Risk Score (LRS) per function from four structural metrics:
| Metric | What it measures |
|---|---|
| CC — Cyclomatic Complexity | Independent decision paths (if/loop/catch/&&/||) |
| ND — Nesting Depth | Maximum depth of nested control structures |
| FO — Fan-Out | Distinct functions called |
| NS — Non-Structured Exits | Early returns, throws, breaks |
LRS = 1.0×R_cc + 0.8×R_nd + 0.6×R_fo + 0.7×R_ns
where each component is log-scaled and capped to prevent outliers from dominating.
In snapshot mode, LRS is combined with git history (churn, touch frequency, recency) and call graph metrics (fan-in, PageRank, SCC membership) to compute an Activity Risk Score and place each function in a triage quadrant:
| Quadrant | Complexity | Activity | Action |
|---|---|---|---|
fire |
High | High | Refactor now |
debt |
High | Low | Schedule before next push |
watch |
Low | High | Monitor |
ok |
Low | Low | Leave it alone |
Risk bands: Low (< 3) · Moderate (3–6) · High (6–9) · Critical (≥ 9)
Supported Languages
TypeScript · JavaScript · Go · Python · Rust · Java · C/C headers · C# · Vue
All 12 file extensions (.ts, .tsx, .mts, .cts, .js, .jsx, .mjs, .cjs, .go, .py, .rs, .java, .c, .h, .cs, .vue) work out of the box.
CI/CD Integration
GitHub Action (zero config)
name: Hotspots
on: [pull_request, push]
jobs:
analyze:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: Stephen-Collins-tech/hotspots-action@v1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
Posts PR comments, generates HTML reports, fails builds on policy violations.
Manual CI
# Fail CI if new critical functions introduced or LRS increases ≥ 1.0
hotspots analyze src/ --mode delta --policy
Exit code 1 on blocking violations, 0 on warnings only.
Key Features
Policy engine — blocks: new critical-risk functions, LRS regressions ≥ 1.0, net repo regression ≥ 5.0. Warns: approaching thresholds, rapid growth > 50%.
Driver labels — each function gets a primary diagnosis: high_complexity, deep_nesting, exit_heavy, high_churn_low_cc, high_fanout_churning, high_fanin_complex, cyclic_dep, or composite.
Pattern detection — 13 named patterns in two tiers: structural (always, e.g. complex_branching, god_function) and enriched (snapshot mode, e.g. churn_magnet, cyclic_hub, volatile_god).
Suppression comments — exclude functions from CI failures while keeping them visible:
// hotspots-ignore: legacy payment processor, rewrite scheduled Q2 2026
function legacyBillingLogic() { ... }
Trained ranker — fit a RandomForest from your repo's bug-fix history:
hotspots train . --blame --eval # train + check P@K vs base rate
Output formats — text (terminal), json (machine), jsonl (streaming), html (interactive), sarif (GitHub Code Scanning).
Configuration — .hotspotsrc.json in project root (auto-discovered):
{
"include": ["src/**/*.ts"],
"exclude": ["**/*.test.ts"],
"thresholds": { "moderate": 3.0, "high": 6.0, "critical": 9.0 },
"weights": { "cc": 1.0, "nd": 0.8, "fo": 0.6, "ns": 0.7 }
}
Documentation
- docs/USAGE.md — workflows, CI setup, output formats, policy engine, suppression, training, snapshot management
- docs/REFERENCE.md — complete CLI reference, all flags, config options, JSON schema, metrics formula
- docs/ARCHITECTURE.md — system design, analysis pipeline, invariants, design decisions
- docs/CONTRIBUTING.md — dev setup, adding languages, release process
Why Hotspots?
vs ESLint complexity rules — ESLint checks one metric in isolation with no git context. Hotspots combines four metrics, git history, and call graph topology into a single prioritized list.
vs SonarQube / CodeClimate — Enterprise platforms requiring server infrastructure. Hotspots is a single binary, zero config, works offline, results in seconds.
vs code reviews — Reviews catch complexity subjectively and miss gradual drift. Hotspots enforces objective thresholds automatically on every commit.
Contributing
- Bug reports: GitHub Issues
- Feature requests: GitHub Discussions
- PRs: see docs/CONTRIBUTING.md
License
MIT — see 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 Distributions
Built Distributions
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 hotspots_cli-1.32.0-py3-none-win_amd64.whl.
File metadata
- Download URL: hotspots_cli-1.32.0-py3-none-win_amd64.whl
- Upload date:
- Size: 5.6 MB
- Tags: Python 3, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.14.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
86193e2db7f0375d39a76ed9b2e02496a13c4d2ce90068794b5f6990321b93b5
|
|
| MD5 |
f888ad968bbff6c7c51e9145f86bf58e
|
|
| BLAKE2b-256 |
bf6a3daf041ff6d768b0d333ba4e2b6445a4266ee0050c0a4afc7ffeb10e6157
|
File details
Details for the file hotspots_cli-1.32.0-py3-none-manylinux_2_39_x86_64.whl.
File metadata
- Download URL: hotspots_cli-1.32.0-py3-none-manylinux_2_39_x86_64.whl
- Upload date:
- Size: 5.9 MB
- Tags: Python 3, manylinux: glibc 2.39+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.14.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0438dc268d53108000b2ace4e4e65176ff86807c61bc3658e9394b2397ac13c3
|
|
| MD5 |
4474850217bda49922933e09075bbb39
|
|
| BLAKE2b-256 |
e1d74377ae7aa586c968eb84c8b7b54c1dc2a279f17b273650c23af1e02a9dcf
|
File details
Details for the file hotspots_cli-1.32.0-py3-none-macosx_11_0_arm64.whl.
File metadata
- Download URL: hotspots_cli-1.32.0-py3-none-macosx_11_0_arm64.whl
- Upload date:
- Size: 5.2 MB
- Tags: Python 3, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.14.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
70bd9e74966807e5f075a9ad714a813b0027791bcefe815423d84c60e56d9056
|
|
| MD5 |
5eac2b2fd712a5e0dea3f83860b10e0d
|
|
| BLAKE2b-256 |
655ee2230847e4a67fb964331f5e7aa6fe0e89b73853ddb187669ab2d3cca2e1
|