|
1 | 1 | --- |
2 | | -title: "I built an automated public log to prove I'm actively maintaining OSS packages" |
| 2 | +title: "npm audit catches CVEs. Nothing catches abandoned packages. So I built a scanner." |
3 | 3 | published: false |
4 | | -description: "How I track 1.6M npm downloads/week across 7 abandoned packages using GitHub Actions, machine-readable evidence snapshots, and zero manual updates." |
5 | | -tags: opensource, github, automation, devops |
| 4 | +description: "A zero-dependency CLI that scans package.json and scores every dependency 0-100 for maintenance health. Plus the full automated monitoring system behind it." |
| 5 | +tags: opensource, javascript, node, npm |
6 | 6 | cover_image: |
7 | 7 | --- |
8 | 8 |
|
9 | | -There's a problem nobody talks about: thousands of npm packages are effectively abandoned while still serving millions of downloads per week. Maintainers disappear. Issues pile up. Security patches sit unmerged. And downstream teams have no way to know. |
| 9 | +## The problem nobody talks about |
10 | 10 |
|
11 | | -I maintain 5 of these packages. The challenge: how do you *prove* ongoing maintenance work to upstream maintainers, grant committees, or employers — without private context? |
| 11 | +Thousands of npm packages are effectively abandoned while serving millions of downloads per week. Maintainers disappear. Issues pile up. Security patches sit unmerged. And `npm audit` won't tell you. |
12 | 12 |
|
13 | | -So I built this: **[oss-maintenance-log](https://github.com/dusan-maintains/oss-maintenance-log)** |
| 13 | +I maintain 7 of these packages — combined 1.4M npm downloads/week. After getting burned by unmaintained transitive dependencies in my own projects, I built a scanner. |
14 | 14 |
|
15 | | -## What it does |
| 15 | +## One command |
16 | 16 |
|
17 | | -Every 6 hours, a GitHub Actions workflow: |
| 17 | +```bash |
| 18 | +npx github:dusan-maintains/oss-maintenance-log express lodash moment request |
| 19 | +``` |
18 | 20 |
|
19 | | -1. Polls the GitHub API for repo metadata (stars, forks, open issues, last push date) |
20 | | -2. Pulls npm download counts (weekly rolling window) |
21 | | -3. Tracks PR states, mergeability, and diff stats |
22 | | -4. Monitors review SLA — flags when maintainer feedback has gone unanswered |
23 | | -5. Generates a prioritized action queue |
24 | | -6. Commits machine-readable JSON + human-readable Markdown snapshots |
25 | | -7. Auto-updates README stats from the fresh data |
| 21 | +``` |
| 22 | + OSS Health Scan Results |
| 23 | + ────────────────────────────────────────────────── |
| 24 | + Scanned: 3 packages |
| 25 | + Average health: 40.8/100 |
| 26 | + ● Critical: 0 ● Warning: 3 ● Healthy: 0 |
26 | 27 |
|
27 | | -Zero manual updates. Everything is public and auditable. |
| 28 | + 🟡 WARNING |
28 | 29 |
|
29 | | -## The packages |
| 30 | + react-hexgrid ███████░░░░░░░░░░░░░ 35.1/100 last push 594d ago |
| 31 | + jquery-modal ████████░░░░░░░░░░░░ 40.5/100 last push 699d ago |
| 32 | + rrule █████████░░░░░░░░░░░ 46.8/100 last push 628d ago |
| 33 | +``` |
30 | 34 |
|
31 | | -Right now I'm tracking: |
| 35 | +## How the scoring works |
32 | 36 |
|
33 | | -| Package | npm/week | Why it needs help | |
34 | | -|---|---|---| |
35 | | -| `rrule` | 1,374,236 | 210 open issues, last push 2024 | |
36 | | -| `python-shell` | 194,847 | Maintainer publicly looking for help | |
37 | | -| `jquery-modal` | 24,399 | "Maintainers Wanted" in README | |
38 | | -| `jquery-tablesort` | 1,667 | "Maintainers Wanted" in README | |
39 | | -| `react-hexgrid` | 1,702 | Maintainer-needed signal in issues | |
| 37 | +Each package gets a weighted health score (0–100): |
40 | 38 |
|
41 | | -Combined: **1,596,851 npm downloads/week** across packages that would otherwise have no active maintenance. |
| 39 | +| Dimension | Weight | What it measures | |
| 40 | +|-----------|--------|-----------------| |
| 41 | +| **Maintenance** | 40% | Last push (exponential decay, 180-day half-life), last npm publish (365-day half-life), open issues ratio | |
| 42 | +| **Community** | 25% | Stars and forks (log₁₀ scaled — 100 stars matters more than the difference between 10k and 11k) | |
| 43 | +| **Popularity** | 20% | npm weekly downloads (log₁₀ scaled) | |
| 44 | +| **Risk** | 15% | Penalty-based: >365 days since push (-4), >100 open issues (-3), >2 years since publish (-2) | |
42 | 45 |
|
43 | | -## Why public? |
| 46 | +Instant flags: `DEPRECATED` → 5/100, `ARCHIVED` → 8/100. |
44 | 47 |
|
45 | | -Accountability. Anyone can verify the work without trusting me. The evidence files are auditable JSON — no private context required. |
| 48 | +The algorithm handles edge cases: |
| 49 | +- High-download packages with no maintainer score high on Popularity but get crushed on Maintenance and Risk |
| 50 | +- Boutique packages with active maintainers score high on Maintenance despite low download counts |
| 51 | +- Mega-repos like Grafana score moderately because their massive issue counts penalize the ratio |
46 | 52 |
|
47 | | -It also creates a paper trail. When I open a PR to a package with 200 open issues, I can link to the evidence log to show I'm not a drive-by contributor. |
| 53 | +## Zero dependencies — on purpose |
48 | 54 |
|
49 | | -## The architecture |
| 55 | +The tool uses only Node.js built-ins (`https`, `fs`, `path`). A dependency health scanner that itself depends on abandoned packages would be... ironic. |
50 | 56 |
|
51 | | -``` |
52 | | -scripts/ |
53 | | - update-evidence.ps1 # Per-repo PR tracking + npm stats |
54 | | - update-ecosystem-status.ps1 # Multi-repo aggregated health snapshot |
55 | | - update-review-sla.ps1 # Review response time monitoring |
56 | | - update-action-queue.ps1 # Prioritized action queue from SLA data |
57 | | - update-readme-stats.ps1 # Patches README with fresh numbers |
58 | | -evidence/ |
59 | | - *.json # Machine-readable snapshots |
60 | | - *.md # Human-readable reports |
61 | | -.github/workflows/ |
62 | | - evidence-daily.yml # Cron: every 6 hours |
| 57 | +## CI integration |
| 58 | + |
| 59 | +```yaml |
| 60 | +# .github/workflows/health-check.yml |
| 61 | +name: Dependency Health Check |
| 62 | +on: |
| 63 | + schedule: |
| 64 | + - cron: "0 9 * * 1" |
| 65 | + pull_request: |
| 66 | + |
| 67 | +jobs: |
| 68 | + scan: |
| 69 | + runs-on: ubuntu-latest |
| 70 | + steps: |
| 71 | + - uses: actions/checkout@v4 |
| 72 | + - uses: actions/setup-node@v4 |
| 73 | + - run: npx github:dusan-maintains/oss-maintenance-log --threshold 30 |
63 | 74 | ``` |
64 | 75 |
|
65 | | -PowerShell + GitHub Actions. Runs on both Windows and Linux (pwsh). No external dependencies beyond the GitHub and npm APIs. |
| 76 | +Exits with code 1 if any critical packages found — works as a PR gate. |
66 | 77 |
|
67 | | -## Use it yourself |
| 78 | +## The full monitoring system |
68 | 79 |
|
69 | | -The repo is marked as a template. Fork it, update the package list in 3 scripts, push — done. MIT licensed. |
| 80 | +The CLI is part of a bigger project. I also built: |
70 | 81 |
|
71 | | -```powershell |
72 | | -# Run locally |
73 | | -./scripts/update-evidence.ps1 |
74 | | -./scripts/update-ecosystem-status.ps1 |
75 | | -./scripts/update-review-sla.ps1 |
76 | | -./scripts/update-action-queue.ps1 |
77 | | -``` |
| 82 | +- **Health trend engine** — 180-day rolling history with 7-day and 30-day deltas. Detects packages that are improving or declining. |
| 83 | +- **Alert system** — Auto-creates GitHub Issues when packages drop below critical threshold. |
| 84 | +- **Review SLA tracker** — Flags when maintainer feedback has gone stale on your PRs. |
| 85 | +- **Interactive dashboard** — Dark-mode Chart.js dashboard with health gauges, radar charts, download distributions. |
| 86 | +
|
| 87 | + |
| 88 | +
|
| 89 | +Everything runs on GitHub Actions every 6 hours. Config-driven — just edit one JSON file with your packages. |
78 | 90 |
|
79 | | -Live dashboard: https://dusan-maintains.github.io/oss-maintenance-log |
| 91 | +**Repo:** [github.com/dusan-maintains/oss-maintenance-log](https://github.com/dusan-maintains/oss-maintenance-log) |
| 92 | +**Live dashboard:** [dusan-maintains.github.io/oss-maintenance-log](https://dusan-maintains.github.io/oss-maintenance-log) |
80 | 93 |
|
81 | 94 | --- |
82 | 95 |
|
83 | | -Curious if others have built similar systems. Is there prior art I missed? And if you maintain packages that need help — open an issue, I'm actively looking for the next ones to adopt. |
| 96 | +What tools do you use to monitor dependency health? I'm curious about existing solutions I might have missed. |
0 commit comments