A comedic but genuinely useful dependency horror visualiser.
Run it in any repo. Depocalypse detects your ecosystem (JavaScript, Python, Rust, Go, …), reads manifests and lockfiles where supported, and scores the project from 0 (Cornetto Clean — the gold standard) to 100 (No Recovery Plan). You get a polished terminal report, a static HTML report, a collectible README-size badge per score, an optional 1200×300 collector poster, and a badge gallery. No server. No paid APIs. No fake CVE claims — only risk signals and heuristics, scored deterministically.
Every score has a collectible badge. The Cornetto badges (0/1/2) are the clean-code chase cards. Every classification is themed as a tiny British genre artefact — Cornetto Clean gets a green CRT survival note, Greater Good a red-and-blue police evidence label, No Recovery Plan a civil-defence leaflet, Beyond Repair a rusted REFUSED plate.
Experimental scanners never pretend unsupported data is complete — reports show scanner confidence, supported features, and missing signals. Unavailable signals do not penalise your score.
Lower is better. Every integer from 0 to 100 unlocks a different classification and a different badge. The Cornetto Trilogy (0/1/2) is legendary clean — genuinely hard to earn. Most modern projects start somewhere in unsettling and have to work their way back.
Every dependency removed is one step closer to the Cornetto.
Tone: dry British humour. Tea is implied.
npx depocalypse# Full experience: terminal report + HTML + badge
npx depocalypse
# Scan only (terminal)
npx depocalypse scan
# HTML report → depocalypse-report/index.html
npx depocalypse report
# README badge — hand-designed PNG for the 11 hero classifications,
# generated SVG fallback for every other score.
# depocalypse-report/badges/readme.png ← primary (when atlas covers this score)
# depocalypse-report/badges/readme.svg ← always written, as a fallback
# depocalypse-report/horror-badge.{png,svg} ← legacy slot, mirrors the primary
npx depocalypse badge # auto: PNG if available, SVG otherwise
npx depocalypse badge --svg # force the generated SVG
npx depocalypse badge --png # require the premium atlas PNG
# Collector poster (1200×300)
# depocalypse-report/badges/poster.svg
npx depocalypse badge --poster
# Every classification 0..100 + Beyond Repair as embeddable artefacts
# PNG for hero scores (0/1/2/31/33/51/61/71/81/100/101)
# SVG fallback for every other score
npx depocalypse badges --all-classifications
# Full badge set (README + poster + earned achievement README badges)
npx depocalypse badges
# Copy-paste-ready Markdown for your README
npx depocalypse badges --readme
# Generate every classification badge (101 + hidden) + gallery.html
npx depocalypse badges --gallery
# Why is lodash here?
npx depocalypse why lodash
# Environment / lockfile check
npx depocalypse doctor
# Force a specific ecosystem (multi-language repos)
npx depocalypse scan --ecosystem python
npx depocalypse scan --ecosystem rust
npx depocalypse scan --ecosystem js
# Scan every detected ecosystem
npx depocalypse scan --allnpm install -D depocalypse
npx depocalypse scanOr clone and hack:
git clone https://github.com/depocalypse/depocalypse.git
cd depocalypse
npm install
npm run build
npm run dev -- scan --cwd ./test/fixtures/minimalThe README badge is the primary collectible, tied to your project's exact score and the classification at that score. Each badge is hand-themed: VHS spines, evidence labels, parchment parish notices, civil-defence leaflets, rusted industrial plates. None of them look like shields.io.
Depocalypse ships two badge tiers that share the same drop-in path:
- Premium PNG (hero atlas). The 11 landmark classifications — Cornetto Clean (0), Greater Good (1), Last Orders (2), Infection Detected (31), Hunted (33), You Opened It (51), Strange Rituals (61), Seen Things (71), Too Deep (81), No Recovery Plan (100), Beyond Repair (hidden 101+) — are extracted from a hand-designed bitmap sprite-sheet (
assets/badges/hero-atlas.png). Each one looks like a real collectible object: a green CRT survival sticker, a police evidence label, a folk-horror parchment, a civil-defence leaflet, an industrial REFUSED plate. - Generated SVG (fallback). Every other score (and every hero score, as a safety net) gets a deterministic 420×120 pure-SVG badge composed from the film theme registry — VHS spines, BBFC cards, ration labels, contour-mapped cave surveys.
depocalypse badge writes both readme.png (when the atlas covers your score) and readme.svg. The HTML report and the --readme markdown snippet point at the PNG when present and the SVG otherwise — no per-project configuration needed.
Drop one into your repo with:
(If your current score isn't a hero classification yet, swap .png for .svg. The depocalypse badges --readme command emits the correct line for your score automatically.)
Or let Depocalypse print the snippet for you (it knows your current title and score):
npx depocalypse badges --readmePick whichever fits your supply chain situation:
| Score | Classification | Badge family |
|---|---|---|
| 0 | Cornetto Clean | Green CRT survival note · CORNETTO CLEAN |
| 1 | Greater Good | Police evidence label · PARISH WATCH |
| 2 | Last Orders | Pub neon sign · LAST ORDERS |
| 31 | Infection Detected | Yellow/black hazard label · QUARANTINE |
| 33 | Hunted | Military ration card · wolf silhouette |
| 51 | You Opened It | Crimson studio horror card · puzzle-box motif |
| 61 | Strange Rituals | Folk parchment parish notice |
| 71 | Seen Things | Deep-space corruption · gravity ring |
| 81 | Too Deep | Cave headlamp survey strip |
| 100 | No Recovery Plan | Civil defence leaflet · NO RECOVERY PLAN |
| >100 | Beyond Repair | Rusted industrial plate · REFUSED |
For collector posts and screenshots, the 1200×300 poster lives at depocalypse-report/badges/poster.svg.
| Ecosystem | Status | Manifests / lockfiles |
|---|---|---|
| JavaScript / TypeScript | Full | package.json, package-lock.json, pnpm-lock.yaml |
| Python | Experimental | pyproject.toml, requirements.txt, poetry.lock, uv.lock |
| Rust | Experimental | Cargo.toml, Cargo.lock |
| Go | Experimental | go.mod, go.sum |
- Full support means a complete dependency graph, install-script detection, duplicate detection, license heuristics, and high scanner confidence (Cornetto tiers 0–2 are earnable).
- Experimental scanners parse direct dependencies and lockfiles where straightforward, count packages, flag suspicious names and git/path deps, and set low or medium confidence. A score floor protects the Cornetto Trilogy from being earned on partial data.
depocalypse doctor lists everything detected in your working directory, including monorepo sub-roots (one level deep).
══ FEATURE PRESENTATION ════════════════════════════════════════════════════
🕯 DEVOUT, ALARMING
— Lovely flat though —
16/100 (raw 16.4, lower is better)
[████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░] 16%
══ COLLECTIBLE CLASSIFICATION ══════════════════════════════════════════════
Current 16 — Devout, Alarming [mild]
Next better 15 — Tidy Until It Isn't
Next worse 17 — Stamped, Classified
Distance to Cornetto 16 points of regret
Every dependency removed is one step closer to the Cornetto.
══ ON THE BACK OF THE BOX ══════════════════════════════════════════════════
Certificate 12 — Mildly unsettling. Suitable with biscuits.
Survival probability 84%
Recommended audience General release. Suitable with cup of tea.
══ DEVELOPER CHASTISEMENT ══════════════════════════════════════════════════
› Left-pad appears to be involved. Naturally.
› request is still here. It has not seen human contact since the coalition government.
› 2 packages installed at multiple versions. Tidy, this is not.
› Every dependency removed is one step closer to the Cornetto.
Achieve a perfect run and you unlock the gold standard:
🍦 CORNETTO CLEAN
— The gold standard —
0/100 (raw 0.0)
Certificate: U
Recommended audience: General release.
Every score from 0 to 100 has its own badge. A typical run writes:
depocalypse-report/
├── index.html
├── classification.json
├── horror-badge.svg # legacy alias for older READMEs
└── badges/
├── main.svg # always points at the current score
└── score-016-devout-alarming.svg # the collectible for THIS scan
Embed the current one in your README:
Or commit a specific collectible to brag (or warn) for posterity:
Each badge is a 1200×300 collectible horror poster generated as pure, self-contained SVG. No external assets, no fonts. Bespoke visual themes per landmark film, with score-driven palette rotation, distress, and pattern density between them:
- Cornetto Clean (0) — CRT terminal panel + zombie hand silhouette, stamped GOLD STANDARD.
- Greater Good (1) — police evidence label, blue/red striping, PARISH WATCH.
- Last Orders (2) — pub-sign neon, alien-replacement glow, REPLACED.
- Infection Detected — biohazard/quarantine tape, distressed yellow/black/red.
- Hunted — military ration label, moon + wolf silhouette, forest green.
- You Opened It — puzzle-box geometry, gold/black/red, OPEN THE BOX.
- Strange Rituals — folk-horror parchment, sunburst, parish notice.
- Seen Things — cosmic black panel, red gravitational ring, star field.
- Too Deep — cave map + headlamp beam, dark slate/red.
- No Recovery Plan — public-information leaflet, nuclear trefoil.
- Beyond Repair (hidden) — industrial failure plate, rust pattern, REFUSED · CANNOT BE REPAIRED.
Remaining classifications fall into visual families (clean comedy, ghost story, infection, folk horror, cosmic, dystopian, public information) with score-driven accent rotation so neighbouring badges always look different.
npx depocalypse badges --galleryWrites all 101 collectible SVGs plus depocalypse-report/badges/gallery.html — a browsable grid showing which badges you have earned in this scan and which are locked, with rarity chips, the visual theme name, and an EARNED marker on the current badge. Cornetto-tier locked badges read: “Clean code required. Probably unnatural.”
The HTML report theme (--theme terminal|vhs|cosmic|slasher) controls the report styling. Badge visuals are driven by each classification's bespoke theme, not the report theme — Cornetto Clean always looks like a CRT terminal regardless of --theme.
| Command | Description |
|---|---|
depocalypse |
Same as scan + report + badge; writes HTML, main + collectible badge, classification.json |
depocalypse scan |
Scan cwd, print terminal report |
depocalypse report |
Write index.html, badges/main.svg, badges/score-NNN-slug.svg, classification.json |
depocalypse badge |
Write the current-score collectible (main + per-score filename) |
depocalypse badges |
Write all 101 collectible badges (+ beyond-repair.svg) |
depocalypse badges --gallery |
Also write badges/gallery.html |
depocalypse why <pkg> |
Show dependency paths to a package |
depocalypse doctor |
Validate lockfile / environment |
| Option | Description |
|---|---|
--cwd <path> |
Project directory (default: current) |
--json |
Machine-readable JSON on stdout |
--output <path> |
Report directory (default: depocalypse-report) |
--open |
Open HTML report in browser |
--theme <name> |
terminal · vhs · slasher · cosmic |
--no-fun |
Factual output only (no jokes) |
--strict |
Exit non-zero if score > threshold |
--threshold <n> |
Strict threshold (default: 80) |
--no-measure-node-modules |
Skip node_modules size walk |
| Manager | v1 support |
|---|---|
npm (package-lock.json) |
First-class |
pnpm (pnpm-lock.yaml) |
Experimental |
Yarn (yarn.lock) |
Detected — not fully supported yet |
If only yarn.lock is present, Depocalypse exits with a helpful message. Run npm install to generate a lockfile, or use pnpm.
Lower is better. Deterministic score from lockfile metadata and heuristics — not a vulnerability database.
Every integer score maps to one unique British/UK horror classification (see src/scoring/classificationTable.ts). There are 101 public entries plus a hidden catastrophic tier.
These are elite clean-code badges. They are not given out lightly — a typical TypeScript project will not earn them.
| Score | Classification | Rarity |
|---|---|---|
| 0 | 🍦 Cornetto Clean — The gold standard. | legendary-clean |
| 1 | 🚓 Greater Good — Parish watch. Very tidy. Slightly intense. | legendary-clean |
| 2 | 🍺 Last Orders — Quietly replaced. Almost perfect, but something is off. | legendary-clean |
To earn 0, a project must have ≤10 unique packages, no duplicates, no install scripts, no suspicious names, no exotic sources, no deprecated heuristic matches, depth ≤5, and more. See computeScore in src/scoring/score.ts.
| Rarity | Score range | Examples |
|---|---|---|
| clean | 3–10 | Allow It, Live Broadcast '92, Monochrome Calm |
| mild | 11–25 | Tidy Until It Isn't, Devout, Alarming, Stamped, Classified |
| unsettling | 26–45 | Infection Detected, Hunted, Festive Musical Zombies |
| grim | 46–65 | Killer Dress, You Opened It, Strange Rituals |
| cursed | 66–90 | Seen Things, Hilltop Haunting, Bureaucratic Dystopia |
| catastrophic | 91–100 | Farm Safety Notice, No Recovery Plan |
Hidden tier (>100 raw)
📼 Beyond Repair — “This system cannot be repaired using known methods.” Certificate: REFUSED.
Every report run writes depocalypse-report/classification.json:
{
"schemaVersion": 2,
"rawScore": 16.4,
"roundedScore": 16,
"classification": { "score": 16, "title": "Devout, Alarming", "rarity": "mild", ... },
"nextBetterClassification": { "score": 15, "title": "Tidy Until It Isn't", ... },
"nextWorseClassification": { "score": 17, "title": "Stamped, Classified", ... },
"distanceToCornettoTier": 16,
"isCornettoTier": false,
"isPerfectCornetto": false
}- Total unique package count
- Transitive / direct ratio
- Duplicate name@version installs
- Packages with install scripts
- Git / tarball /
file:sources - Deprecated-name heuristics (e.g.
request,left-pad) - Maximum dependency depth
node_modulesdisk size (when measured)- Unknown licenses
- Suspicious package names (typo-adjacent, risky words)
Output is stable between runs (no random jokes) so CI stays predictable.
Fail the build when horror exceeds your tolerance:
- name: Depocalypse
run: npx depocalypse scan --strict --threshold 75 --no-measure-node-modulesJSON for dashboards:
npx depocalypse scan --json --no-fun > depocalypse.jsondepocalypse-report/index.html is a standalone static file (embedded CSS + JS):
- Cinematic title card with exact-score classification, BBFC-style certificate, and score gauge
- Collectible classification: current badge, next better/worse, distance to Cornetto Clean
- On the back of the box: survival probability, time until npm install regret, recommended backup maintainers, recommended audience
- Prophecies & portents: Architectural Regret Forecast, Supply Chain Séance, Dependency Necromancy Index, Likelihood of Junior Dev Panic, Probability somebody added this from Stack Overflow at 2am
- Metric cards & score factor breakdown
- Collapsible dependency tree (top levels)
- Heaviest branches, duplicates, suspicious packages
- Install-script packages, licence bars
- Precomputed “why” paths for hot transitive packages
- Developer chastisement & remediation
The whole thing has a CRT scanline + grain overlay, with theme variants for VHS rental, crimson studio horror, civil-defence public-information, and folk-horror parish. No build step required to open the report.
v1 uses risk heuristics, not full vulnerability scanning. Depocalypse does not query OSV, npm audit, or CVE APIs. Signals like “deprecated heuristic” or “suspicious name” are hints — investigate before you panic (or before you ignore).
Ecosystems
- Poetry / uv full transitive graph support
- Cargo feature graph & target-specific deps
- Go module indirect dependency graph
- Maven / Gradle
- NuGet
- Composer (PHP)
- Ruby Bundler
- Monorepo aggregate horror report
Product
- OSV vulnerability lookup
- Registry freshness lookup
- GitHub Actions integration
- PR comments
- Lockfile diff mode
- SBOM export
- VSCode extension
- Serious enterprise mode
npm install
npm run build
npm test
npm run dev -- scan --cwd test/fixtures/minimalsrc/
cli.ts
ecosystems/ # plugin scanners: javascript, python, rust, go
scanner/ # dispatch, graph, why, package-lock parsers
scoring/ # score, classifications, chastise
report/ # html, badge, themes
output/ # terminal, json
utils/
test/fixtures/
MIT — see LICENSE.
Several dependencies are deprecated. Much like British Rail.