epitaph.
your dependencies are dying. epitaph finds the bodies.
You already audit for CVEs. epitaph audits for abandonment. It reads your manifest, checks every package against GitHub and npm, and tells you which ones are dead, dying, or on life support.
npx epitaph-devrun in any project. zero config.
epitaph v0.1.0 — scanning package.json (47 dependencies)
GRADE PACKAGE SIGNALS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
F request ⚰️ Deprecated since Feb 2020
F event-stream ⚰️ Archived · supply chain incident
D cool-lib 👤 Bus factor: 1 · 14mo since human commit
C legacy-helper 👤 Bus factor: 1 · active 2w ago
B ms 📦 Stable (1M+ downloads, no issues)
A express 🟢 12 contributors · funded · active
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
47 scanned · 2 dead · 1 warning · 1 caution · 43 healthyHow it works
One command. Every dependency graded.
Reads your manifest
Parses package.json and extracts every dependency. Production, dev, or both.
Queries npm + GitHub
Fetches registry data, commit history, issue responsiveness, funding status, and download trends.
Scores A through F
8 weighted signals. Bot filtering. "Done package" exception. Dead deps flagged, healthy deps confirmed.
What it checks
8 signals. Weighted scoring.
Last human commit
25%Filters out Dependabot, Renovate, and other bots. Only counts humans touching source files.
Bus factor
25%How many distinct humans committed in the last 12 months. One person = one token away from disaster.
Issue responsiveness
20%Median time for a maintainer to respond. Ignored issues = unpatched bugs.
Open issue ratio
15%Percentage of all issues still open. High ratio = backlog nobody is clearing.
Funding
10%GitHub Sponsors, Open Collective, Tidelift. Funded projects survive maintainer burnout.
Download trend
5%Growing, stable, or declining. Declining downloads = the ecosystem is moving on.
Archived
instant FRepo explicitly marked archived. No PRs, no fixes, no future.
Deprecated
instant FPackage marked deprecated on the registry. Maintainer said stop using it.
Packages with >1M weekly downloads and no open issues get a floor score of C.
"Done" packages like ms and inherits aren't penalized for being finished.
Why not X?
Nothing else does this.
Finds known CVEs
Doesn't know if anyone is around to fix them
Health score per package
Web-only, one at a time, no CLI, no CI
Detects malware
Enterprise product, not a lightweight dev tool
Security posture per repo
Per-repo, not per-manifest
Newer version available?
Deprecated + no newer version = "up to date"
Grades
What each grade means.
Actively maintained. Multiple contributors, responsive to issues, funded or widely adopted.
80–100Healthy. Recent commits, reasonable contributor count, no red flags.
60–79Stable but aging. Low activity or single maintainer, but still functional. Watch it.
40–59At risk. Infrequent commits, bus factor 1, slow or no issue response. Plan a replacement.
20–39Dead, deprecated, archived, or compromised. Do not depend on this.
0–19GitHub Token
Better data with a token.
Without a token, epitaph uses npm data only — enough to catch deprecated and archived packages. With a token, you get commit history, bus factor, issue response times, and funding data. That's what powers the D/C grades that catch slow-dying packages.
Pass it inline
npx epitaph-dev --token YOUR_TOKENSet as env var (recommended)
export GITHUB_TOKEN=YOUR_TOKENAdd to ~/.bashrc or ~/.zshrc. epitaph picks it up automatically.
How to create a token
- 1
- 2
Click Generate new token (classic)
- 3
Give it any name — e.g. epitaph
- 4
Select one scope: public_repo — read-only access to public repos
- 5
Copy the token and set it as GITHUB_TOKEN
epitaph only reads public repository data. It never writes to GitHub, never accesses private repos, and only needs the minimal public_repo scope.
Get started
Pick how you want to use it.
Terminal
Run once in any project. Nothing to install, nothing to configure.
npx epitaph-devGitHub Action
Add one file. Runs on every PR that touches package.json and weekly on schedule.
No token setup needed — secrets.GITHUB_TOKEN is injected automatically by GitHub on every run.
name: epitaph
on:
schedule:
- cron: '0 9 * * 1'
pull_request:
paths: ['package.json']
jobs:
health:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: Ijtihed/epitaph@v1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
fail-grade: D
production-only: trueAI Prompt
Paste into Cursor, Claude Code, or Copilot. AI does the rest.
Add epitaph to this project. Create .github/workflows/epitaph.yml that runs on every PR using Ijtihed/epitaph@v1. Then run npx epitaph-dev locally and fix any dependency health issues it finds.