Download velocity
Trailing-90-day install volume across npm, PyPI, Maven, crates.io, Go modules, and RubyGems. Log-scaled and normalized per ecosystem so a niche crate can compete fairly with a mainstream framework.
Weight · 25%Every package in OpenLib's 1,247,392-package catalog is scored on the same four production signals. This document explains what those signals are, how they are normalized, and how they are combined — so engineering managers, security leads, and procurement teams can cite a defensible number in vendor reviews.
No paid placements, no editor picks, no SEO boosts. The composite score is a deterministic function of four public, measurable signals — each one sampled from data engineering managers already check during a dependency review.
Trailing-90-day install volume across npm, PyPI, Maven, crates.io, Go modules, and RubyGems. Log-scaled and normalized per ecosystem so a niche crate can compete fairly with a mainstream framework.
Weight · 25%Median time between a GitHub issue being opened and closed (or triaged with a maintainer response). Penalizes projects with rotting backlogs and rewards those that close the loop quickly.
Weight · 25%Distribution of commits, reviews, and release rights across active contributors. A project driven by a single maintainer with no co-maintainer scores lower than one with healthy succession depth.
Weight · 25%Severity-weighted count of published CVEs against the package and its direct dependencies over the trailing 24 months, discounted by how quickly each was patched after disclosure.
Weight · 25%Each pillar is rescaled to a 0–100 range using a piecewise-linear normalization that is calibrated per ecosystem. The composite score is the equal-weighted mean of those four pillars, then clipped and rounded to one decimal.
PRI = clip( ( DV + IH + BF + CV ) / 4, 0, 100 )
Raw install counts include CI farms, mirror traffic, and dependency-confusion noise. OpenLib deduplicates installs by SHA-256 of (registry client IP, package version, user-agent class) over a 24-hour window, then log-scales the remaining count against the per-ecosystem 95th percentile recorded in the trailing 12 months. A package at the 95th percentile scores 100; the median scores 62; the 5th percentile scores 18.
DV = round( 100 · log10(1 + installs_dedup) / log10(1 + p95_installs) )
We sample the median time-to-first-maintainer-response across the trailing 200 issues (or all issues if the project has fewer). Projects under 12 hours score 100; projects at 14 days score 50; projects over 90 days score 5. Issues tagged question, discussion, or duplicate are excluded to avoid penalizing helpful maintainers for being conversational.
IH = piecewise_linear( median_first_response_hours, [(12,100),(336,50),(2160,5)] )
We compute a Herfindahl–Hirschman Index over commit authorship in the trailing 12 months, then subtract a co-maintainer credit for every contributor with release-publish rights on the upstream registry. The score is 100 when the top contributor holds less than 25% of recent commits AND at least three co-maintainers hold publish rights. A solo-maintainer project with no co-maintainer scores 10.
BF = clamp( 100 - 2.5·HHI_top + 5·co_maintainers, 0, 100 )
Each CVE published against the package or its direct dependencies in the trailing 24 months contributes a penalty of CVSS × 4 points, discounted linearly so a 2-year-old CVE carries 12.5% weight. A patch released within 7 days of disclosure recovers 70% of that penalty. A package with zero CVEs and a clean SBOM scores 100. A package with a fresh unpatched RCE scores below 20.
CV = clamp( 100 - Σ penalty_i · discount_i · (1 - 0.7·fast_patch_i), 0, 100 )
Numbers an engineering manager should see before citing any Index score internally.
Yes — and that is the point.
The full catalog is available as a Parquet export under CC-BY-SA 4.0, refreshed nightly. Methodology weights are versioned: every Index score in the database carries a methodology_version field, so a score produced under v3.0 can be recomputed today by pinning the formula version. The public REST API exposes a ?explain=1 flag that returns the four pillar sub-scores and the normalization buckets used, for any package, with no authentication required.
Researchers at eleven universities have used the export to replicate OpenLib's rankings against ground-truth dependency graphs scraped from production monorepos. The published error margin against these independent replications is under 0.4 points on the 0–100 scale. If your team finds a discrepancy larger than that, open an issue on openlib/methodology and we will publish a post-mortem within ten working days.
If yours is not here, write to [email protected] — we publish new answers monthly.
No. The score is a deterministic function of four public signals — downloads, issue response time, contributor concentration, and CVE history. None of these are sellable, sponsorable, or boostable through any paid tier. The Pro tier ($19/mo) mirrors private packages into a team's index; it does not alter the public score of any package.
A package with zero published CVEs is not assumed to be safe — it is assumed to be unobserved. The CVE pillar scores 100 only when the SBOM is clean AND the package has been in the index for at least 12 months AND its direct dependencies have been scanned by at least one of the major advisory databases (NVD, GHSA, OSV). New packages are held at a neutral 60 until they accumulate enough observation history to be scored fairly.
Bus-factor is an excellent long-term risk signal but a noisy short-term one. A solo maintainer who has shipped every release for six years is, today, a very low operational risk — and penalizing them heavily for being solo would distort rankings against small-but-excellent libraries. We expose bus-factor as a separate filterable attribute so security and succession planning teams can weight it differently in their own private indexes without affecting the public composite.
Yes — citation is explicitly encouraged. The recommended citation format is in the methodology repository at github.com/openlib/methodology, and includes the methodology version, the retrieval date, and the SHA-256 of the Parquet snapshot you queried against. A PDF version of this page is available for inclusion in procurement packets; request it via the contact email above.