epitaph

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-dev

run 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 healthy

How it works

One command. Every dependency graded.

1

Reads your manifest

Parses package.json and extracts every dependency. Production, dev, or both.

2

Queries npm + GitHub

Fetches registry data, commit history, issue responsiveness, funding status, and download trends.

3

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.

1

Last human commit

25%

Filters out Dependabot, Renovate, and other bots. Only counts humans touching source files.

2

Bus factor

25%

How many distinct humans committed in the last 12 months. One person = one token away from disaster.

3

Issue responsiveness

20%

Median time for a maintainer to respond. Ignored issues = unpatched bugs.

4

Open issue ratio

15%

Percentage of all issues still open. High ratio = backlog nobody is clearing.

5

Funding

10%

GitHub Sponsors, Open Collective, Tidelift. Funded projects survive maintainer burnout.

6

Download trend

5%

Growing, stable, or declining. Declining downloads = the ecosystem is moving on.

7

Archived

instant F

Repo explicitly marked archived. No PRs, no fixes, no future.

8

Deprecated

instant F

Package 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.

npm audit

Finds known CVEs

Doesn't know if anyone is around to fix them

Snyk Advisor

Health score per package

Web-only, one at a time, no CLI, no CI

Socket.dev

Detects malware

Enterprise product, not a lightweight dev tool

OpenSSF Scorecard

Security posture per repo

Per-repo, not per-manifest

npm outdated

Newer version available?

Deprecated + no newer version = "up to date"

Grades

What each grade means.

A

Actively maintained. Multiple contributors, responsive to issues, funded or widely adopted.

80–100
B

Healthy. Recent commits, reasonable contributor count, no red flags.

60–79
C

Stable but aging. Low activity or single maintainer, but still functional. Watch it.

40–59
D

At risk. Infrequent commits, bus factor 1, slow or no issue response. Plan a replacement.

20–39
F

Dead, deprecated, archived, or compromised. Do not depend on this.

0–19

GitHub 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

bash
npx epitaph-dev --token YOUR_TOKEN

Set as env var (recommended)

bash
export GITHUB_TOKEN=YOUR_TOKEN

Add to ~/.bashrc or ~/.zshrc. epitaph picks it up automatically.

How to create a token

  1. 1

    Go to github.com/settings/tokens

  2. 2

    Click Generate new token (classic)

  3. 3

    Give it any name — e.g. epitaph

  4. 4

    Select one scope: public_repo — read-only access to public repos

  5. 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.

bash
npx epitaph-dev
--json--production-only--fail-grade D

GitHub 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.

.github/workflows/epitaph.yml
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: true

AI Prompt

Paste into Cursor, Claude Code, or Copilot. AI does the rest.

prompt
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.