How Health Scores Help Developers Choose Better Packages
·PkgPulse Team
TL;DR
GitHub stars are vanity metrics. Health scores are actionable. A package with 50K GitHub stars might have 0 commits in 2 years, 200 open issues, and declining downloads. A package with 5K stars might have weekly releases, 10 active maintainers, and 2M weekly downloads. Health scores aggregate the signals that actually predict maintenance quality and longevity — so you make package decisions on data, not hype.
Key Takeaways
- GitHub stars: correlation with quality = 0.2 — stars measure popularity at a point in time
- Downloads + trend — the strongest signal of continued adoption
- Last publish date — packages not updated in 18+ months carry risk
- Issue velocity — fast issue response = active maintainer
- TypeScript coverage — now a first-class quality signal
- Dependency count — high transitive deps = higher attack surface + bundle size
Why GitHub Stars Mislead
Real examples of star count vs health disconnect:
Package A: 52,000 stars
Last commit: 18 months ago
Open issues: 847 (no responses for 6 months)
Weekly downloads: 120K (declining 40% YoY)
TypeScript support: None (@types/packageA missing)
Verdict: DO NOT USE for new projects
Package B: 3,200 stars
Last commit: 3 days ago
Open issues: 12 (average response: 2 hours)
Weekly downloads: 2.4M (growing 80% YoY)
TypeScript support: Built-in, strict
Verdict: Excellent choice
Stars reflect: discovery, viral blog posts, trending periods
Stars don't reflect: maintenance activity, community responsiveness, longevity
What Health Scores Measure
Dimension 1: Maintenance Activity
Signals:
- Days since last npm publish (lower = better)
- Commit frequency (average per month)
- Issue close rate (% of issues resolved in 30 days)
- PR merge rate and time
Scoring rubric:
Published < 30 days: 30/30 points
Published 30-90 days: 25/30
Published 90-365 days: 15/30
Published 1-2 years: 5/30
Published > 2 years: 0/30
Why this matters:
- Security vulnerabilities get patched
- Breaking changes in dependencies get fixed
- New Node.js/TypeScript versions get support
Dimension 2: Adoption and Growth
Signals:
- Weekly download count (absolute)
- Download trend (3-month and 12-month growth rate)
- Dependents count (packages that depend on it)
Why downloads beat stars:
- Stars can be bought/gamed (GitHub star purchasing is a real market)
- Downloads represent actual usage in CI/CD, not just bookmarks
- Download trend reveals momentum (growing = healthy ecosystem interest)
- Dependents count reveals lock-in to the ecosystem
Interpreting download trends:
+50%+ YoY: Rapidly growing, strong momentum
+10-50%: Healthy growth
-10% to +10%: Stable
-10% to -30%: Slight decline — watch
-30%+ YoY: Significant decline — evaluate alternatives
Dimension 3: TypeScript Support
Scoring levels (0-20 points):
20 pts: Written in TypeScript, types bundled
15 pts: Bundled .d.ts files (not written in TS but types included)
10 pts: DefinitelyTyped @types/ package available
5 pts: Types available but outdated
0 pts: No types, any usage everywhere
Why this matters in 2026:
- 83% of new projects use TypeScript
- Packages without types require manual type declarations
- Type accuracy predicts API correctness (if types are wrong, API docs often are too)
Dimension 4: Security Posture
Signals:
- Known CVE count (from npm audit database)
- Time to patch past CVEs
- Dependency count (attack surface)
- Package provenance (verified build chain)
Scoring:
0 known CVEs: 30/30
1-2 CVEs, patched: 20/30
1-2 CVEs, unpatched: 10/30
3+ CVEs: 0/30
Transitive dependency count:
< 5 deps: 20/20
5-20 deps: 15/20
20-50 deps: 10/20
50+ deps: 5/20
Dimension 5: Bundle Efficiency
Signals:
- Gzipped bundle size
- Tree-shaking support (sideEffects: false in package.json)
- ESM support (better tree-shaking for bundlers)
- Dependency weight (deps bundle size)
Scoring:
< 5KB gzip: 20/20
5-25KB: 15/20
25-100KB: 10/20
100-500KB: 5/20
> 500KB: 0/20
Real-World Health Score Examples
High Health Score (Drizzle ORM: 92/100)
Drizzle ORM health breakdown:
Maintenance: 29/30 (published 5 days ago)
Adoption: 25/25 (2M downloads, +400% YoY)
TypeScript: 20/20 (written in TypeScript, excellent inference)
Security: 28/30 (0 CVEs, 12 transitive deps)
Bundle efficiency: 17/20 (3KB runtime, ESM support)
Composite: 92/100
Interpretation: Excellent choice for new projects.
Active development, strong growth, TypeScript-first.
Declining Health Score (TypeORM: 52/100)
TypeORM health breakdown:
Maintenance: 15/30 (last published 4 months ago, slow issue response)
Adoption: 18/25 (3M downloads but -15% YoY)
TypeScript: 15/20 (TypeScript support but legacy decorator approach)
Security: 14/30 (2 unpatched moderate CVEs, high dep count)
Bundle efficiency: 10/20 (larger bundle, CJS-first)
Composite: 52/100
Interpretation: Still works, but declining. For new projects,
consider Prisma or Drizzle instead.
How to Read Health Scores in Context
Health scores are useful signals, not absolute verdicts:
High score but wrong choice:
- styled-components: 75/100 (active, popular) but RSC-incompatible
→ High health score, but wrong choice for Next.js 15 app router
Low score but acceptable:
- An internal analytics package: 40/100 (slow updates)
→ Slow updates are fine if the API is stable and you don't need new features
Score trajectories matter:
- Package at 80/100 but declining 5 points/quarter → better alternatives exist
- Package at 60/100 but improving rapidly → promising, monitor it
Building Your Own Package Evaluation Process
# 5-minute package evaluation checklist:
1. Check PkgPulse health score
→ pkgpulse.com/compare/[package-a]-vs-[package-b]
2. Check download trend
→ npmtrends.com for 12-month view
3. Check last publish date
→ npm view [package] time.modified
4. Check TypeScript support
→ npmjs.com/package/[package] → sidebar shows "TypeScript"
5. Check bundle size
→ bundlephobia.com/package/[package]
6. Scan GitHub issues
→ Filter by "no response" label — are issues being ignored?
7. Check dependents
→ npmjs.com/package/[package] → "Used by N packages"
→ High dependents = slower to abandon
# Total time: 5-10 minutes
# Catches 90% of bad package choices
See detailed health scores and download trends for any npm package comparison on PkgPulse.
See the live comparison
View react vs. vue on PkgPulse →