Skip to content
LFX Insights

Health Score Explained ​

LFX Insights surfaces two independent assessments for open source projects: a Lifecycle state and a Health Score. Together, these replace the previous single composite score and answer two distinct questions:

  • Lifecycle: what state is this project in?
  • Health Score: how well-maintained is it?

⚠️ Please note

No score captures all the nuance of an open source project. Different projects serve different goals: some are mature and stable by design, others are experimental or niche. These assessments are meant to highlight signals and risks, not to make final judgments. Always consider context alongside the numbers.

The Assessments ​

AssessmentQuestion answeredOutput
LifecycleWhat state is this project in?One of six states: Active, Stable, Declining, Inert, Abandoned, Archived
Health ScoreHow well-maintained is it?0–100, independent of popularity

This methodology was developed with community input. You can read the full discussion and the feedback that shaped these decisions in GitHub Discussion #1939.

Lifecycle State ​

States ​

StateWhat it means
ActiveRegular commits in the last 6 months and maintainer is responsive to issues and pull requests.
StableCommit activity has dropped more than 50% compared to the prior period, but a release was published within the last 12 months, fewer than 50 issues are open, and no critical vulnerabilities are unresolved.
DecliningCommits in the last 6 months are less than half the prior 6 months, and the number of newly opened issues has increased. A sign the project is under pressure.
InertNo commits in 18 or more months, and no open issues or pull requests. Nothing to judge responsiveness by — a quiet project, not a neglected one.
AbandonedOpen issues or pull requests have gone unanswered for 90 to 180 days, and no maintainer activity in the last 18 months.
ArchivedExplicitly archived in the repository host or marked deprecated or yanked in the package registry.

TIP

"Silence alone is not abandonment — ignoring people is." A finished utility with no open issues, no CVEs, and no need for further development gets Inert, not Abandoned. The Abandoned state requires evidence of neglect: open items piling up while maintainers are absent. This distinction came directly from community feedback on the methodology.

For multi-repo projects, the project takes the best state across all its repositories: Active beats Stable, Stable beats Declining, and so on down to Archived.

Health Score (0–100) ​

The Health Score measures how well-maintained a project is, independent of how popular or critical it is. A widely-used project with poor maintainer responsiveness will score low here.

Health Score (0–100) = Maintainer Health (0–40 pts) + Security and Supply Chain (0–35 pts) + Development Activity (0–25 pts)

Rating Bands ​

ScoreLabelWhat it signals
85–100ExcellentWell-maintained, secure, active or intentionally stable
70–84HealthyIn good shape with minor gaps
50–69FairSome concerning signals; may need attention
30–49ConcerningMultiple risk signals; stewardship candidate
0–29CriticalSerious gaps; likely needs intervention

1. Maintainer Health (0–40 pts) ​

A project with responsive maintainers will fix CVEs, clear backlogs, and ship fixes. Without them, the other signals are just a timer.

1.1 Maintainer Responsiveness (max 15 pts) ​

Measures the median time for a non-author to respond to newly opened issues and pull requests. The score uses the average of the issue and PR response medians. Bot and automation activity is excluded so only genuine human responses count.

  • 15 pts: Median response time under 24 hours
  • 12 pts: Median response time under 3 days
  • 9 pts: Median response time under 1 week
  • 5 pts: Median response time under 1 month
  • 2 pts: Median response time under 3 months
  • 0 pts: Median response time 3 months or more, or no response data available

Projects with no open issues or pull requests in the measurement window have no response data. This sub-signal scores 0 pts (not imputed) because the signal is available — there is simply no activity to measure. Only blocked sub-signals have their missing weight imputed at the population median rate.

1.2 Bus Factor (max 18 pts) ​

Counts the number of people who are actively maintaining the project, taking the higher of two sources: the official maintainer roster and the set of people observably performing review and merge actions in the last 12 months. This corrects for curated rosters that undercount large, community-maintained projects.

  • 18 pts: 5 or more active maintainers
  • 15 pts: 3 or 4 active maintainers
  • 6 pts: 2 active maintainers
  • 3 pts: 1 active maintainer
  • 0 pts: No active maintainers

1.3 Organizational Diversity (max 7 pts) ​

Measures how many distinct organizations the active maintainers are affiliated with, using contributor affiliation data. Projects maintained by contributors from multiple independent organizations are more resilient to any single organization withdrawing support.

  • 7 pts: Maintainers from 3 or more organizations
  • 5 pts: Maintainers from 2 organizations
  • 2 pts: All maintainers from 1 organization
  • 0 pts: Affiliation unknown

2. Security and Supply Chain (0–35 pts) ​

A project's security posture depends on both what it ships and how it is built. This category measures known vulnerabilities, documented security practices, supply chain integrity, and the health of the project's own dependencies. The 5 points formerly reserved for Supply Chain Integrity have been permanently reallocated to the other sub-signals; the category total remains 35 pts.

2.1 Open Vulnerabilities ​

Counts unresolved security advisories scoped to the repository, sourced from OSV and GHSA. Points are deducted by severity:

  • 10 pts: No open vulnerabilities
  • Points deducted per open advisory: 6 per Critical, 3 per High, 1 per Moderate (minimum 0)

If no vulnerability scan data is available for the repository, missing advisory counts are treated as zero. The project is scored as having no open vulnerabilities and receives the full 10 points. Absent scan data cannot currently be distinguished from a clean scan in the score calculation.

2.2 Security Practices ​

Checks whether the repository has adopted documented security practices:

  • 2 pts: SECURITY.md file present
  • 2 pts: Branch protection enabled on the default branch
  • 2 pts: Required code reviews on pull requests
  • 2 pts: Required status checks before merging

INFO

Security practices are currently evaluated for GitHub repositories only. GitLab and Gerrit repositories have this sub-signal blocked; its missing weight is imputed at the population median rate.

2.3 OpenSSF Scorecard ​

Uses a banded mapping from the OpenSSF Scorecard's 0–10 raw score, calibrated to the real distribution of scores across tracked repositories:

  • 7 pts: Scorecard raw ≥ 7.0
  • 5 pts: Scorecard raw ≥ 5.5
  • 4 pts: Scorecard raw ≥ 4.0
  • 2 pts: Scorecard raw ≥ 2.5
  • 0 pts: Scorecard raw < 2.5

Currently available for GitHub-hosted repositories only. GitLab and Gerrit repositories have this sub-signal blocked; its missing weight is imputed at the population median rate.

2.4 Dependency Health ​

Evaluates the security posture of the project's direct dependencies:

  • 5 pts: No direct dependencies with known high or critical vulnerabilities
  • 3 pts: 1 or 2 vulnerable dependencies
  • 1 pt: 3 to 5 vulnerable dependencies
  • 0 pts: More than 5 vulnerable dependencies

Available only for repositories that publish tracked packages. Repositories without published packages have this sub-signal blocked.

2.5 Supply Chain Integrity ​

Assesses build provenance attestation, artifact-to-repository consistency, and publisher account security. This sub-signal is in development and is currently blocked for all projects. Its weight has been permanently reallocated to the other available Security sub-signals; projects are not penalized and the Security category maximum remains at 35 pts.

3. Development Activity (0–25 pts) ​

Development Activity rewards recent releases, commits, resolved issues, and merged pull requests. Projects with no activity across these signals score low here. The Lifecycle state provides additional context — a Stable classification signals to users that low activity is intentional — but it does not change the underlying point formula.

3.1 Release Cadence (max 8 pts) ​

Measures how recently and regularly the project has published releases. Counted over distinct release days to prevent burst-publishing in monorepos from inflating the score.

  • 8 pts: Latest release within 90 days and consistent cadence (releases at least every 90 days)
  • 6 pts: Latest release within 180 days
  • 4 pts: Latest release within 1 year
  • 2 pts: Latest release within 2 years
  • 0 pts: No release in over 2 years, or no releases tracked

Available only for repositories that publish tracked packages. Repositories without published packages have this sub-signal blocked.

3.2 Commit Activity (max 5 pts) ​

Counts commits authored in the last 6 months on the cleaned activity stream (bots and automation excluded).

  • 5 pts: 50 or more commits
  • 4 pts: 20 to 49 commits
  • 3 pts: 5 to 19 commits
  • 1 pt: 1 to 4 commits
  • 0 pts: No commits

3.3 Issue Resolution (max 7 pts) ​

Combines two independent measures over the last 12 months: how many issues were resolved, and how quickly. Only non-bot activity is included. Points from each component are added together.

Close ratio (max 4 pts) — issues closed relative to issues opened:

  • 4 pts: 80% or more of opened issues were closed
  • 2 pts: 50% or more of opened issues were closed
  • 0 pts: Fewer than 50% closed, or no issues in the period

Median time to close (max 3 pts):

  • 3 pts: Median close time under 7 days
  • 2 pts: Median close time under 30 days
  • 0 pts: 30 days or more, or no closed issues in the period

Gerrit repositories do not ingest issue data. This sub-signal is blocked for Gerrit-only projects; its missing weight is imputed at the population median rate.

3.4 PR Merge Health (max 5 pts) ​

Combines two independent measures over the last 12 months: what fraction of pull requests were merged rather than abandoned, and how quickly. Points from each component are added together. For Gerrit projects, changesets and patchsets are mapped to the same metrics.

Merge ratio (max 3 pts) — merged pull requests relative to all closed pull requests:

  • 3 pts: 70% or more of closed pull requests were merged
  • 1 pt: 40–69% of closed pull requests were merged
  • 0 pts: Fewer than 40% merged, or no closed pull requests in the period

Median time to merge (max 2 pts):

  • 2 pts: Median merge time under 7 days
  • 1 pt: Median merge time under 30 days
  • 0 pts: 30 days or more, or no merged pull requests in the period

Handling Missing Data ​

Not every signal is available for every project. Insights uses two layers of handling so projects aren't penalized for gaps in data coverage.

Layer 1, sub-signal blocked: if a specific sub-signal cannot be computed (for example, OpenSSF Scorecard is unavailable for a GitLab repository), the missing weight is imputed at the population median rate for that sub-signal — the rate observed across all projects where the signal is available. This prevents a project that has a signal measured from being disadvantaged relative to one that does not.

Layer 2, category requirements:

A category is marked unavailable when the repository platform does not support any of its sub-signals — for example, a Gerrit project with no package data may have no computable Security sub-signals. Once a category is unavailable it is dropped from the composite entirely.

  • If all 3 categories are available, the Health Score is computed normally, out of a maximum of 100.
  • If exactly 1 category is unavailable, the score is computed from the 2 available categories and shown out of a reduced maximum: 60 if Maintainer Health (40 pts) is missing, 65 if Security and Supply Chain (35 pts) is missing, or 75 if Development Activity (25 pts) is missing. The rating label carries an asterisk (for example, "Healthy*") to signal that not all categories were observed, and a "Partial score (2/3 categories)" link under the label explains which category is missing. The share badge reads the same way, for example "Healthy* (52/65)".
  • If 2 or more categories are unavailable, the Health Score is marked unavailable rather than computed from insufficient evidence.

The Health Score is always either a number out of 100 (full), a number out of a reduced maximum with a partial indicator, or explicitly unavailable — never a silent zero or blank. This way you can always distinguish "we could not measure this" from "this project scored poorly."

Multi-Repo Projects ​

An Insights project can span multiple repositories. Sub-signals are computed per repository, then rolled up to the project level:

  • Health Score and category rollups: median across all active, non-excluded repositories. The median is used for the total score and each of the three category rollups (Maintainer Health, Security and Supply Chain, Development Activity). Using the median prevents a long tail of less-active repositories from dragging down projects with strong flagship repos.
  • Lifecycle state: best-state-wins. One active repository makes the project active, regardless of the state of other repositories.

Repositories marked as excluded (for example, experimental sandbox repos) are not included in scoring. This prevents an inactive experimental repository from dragging down a project's Health Score.

Platform and Data Coverage ​

Insights collects data from GitHub, GitLab, and Gerrit. Not all signals are available on every platform, and not all projects publish tracked packages.

GitLab projects:

Security practices and OpenSSF Scorecard are currently GitHub-only. GitLab projects will typically have these sub-signals imputed at the population median rate (Layer 1). If the Security category itself becomes unavailable, the Health Score is computed from the remaining 2 categories and shown with a partial indicator. Health Score still computes from Maintainer Health and Development Activity. Broader security signal coverage for GitLab is in development.

Gerrit projects:

Gerrit does not ingest issue data in the same format as GitHub and GitLab. Issue Resolution and Security Practices are typically blocked. PR Merge Health is available — Gerrit changesets and patchsets are mapped to the same merge metrics. Commit Activity and Bus Factor also remain available.

Projects without published packages:

Release Cadence and Dependency Health are package-mediated signals. Projects that do not publish to a tracked registry (npm, PyPI, Maven, and others) will have these sub-signals blocked; their missing weight is imputed at the population median rate. Supply Chain Integrity is permanently blocked for all projects and its weight has been explicitly reallocated within the Security category.

Projects with partial data across repos:

For multi-repo projects, sub-signals in a partial coverage state are computed over the subset of repositories where data is available. The score reflects what can be observed.

INFO

Health Score comparisons across projects with different platform or data coverage are not directly comparable. A project with full GitHub and package data is scored on more signals than one on Gerrit with no published packages. Coverage details are always shown alongside the score.

How This Differs from the Previous Health Score ​

INFO

The original Insights Health Score was a single 0–100 value, computed as an equal-weight mean of four sub-scores: Contributors (25 pts), Popularity (25 pts), Development (25 pts), and Security and Best Practices (25 pts). The current methodology replaces that with independent assessments and re-weighted health categories.

AspectOriginal Health ScoreCurrent methodology
OutputSingle score (0–100)Two assessments: Lifecycle (state), Health Score (0–100)
Health categories4 equal categories at 25 pts each3 weighted categories: Maintainer (40), Security and Supply Chain (35), Development Activity (25)
PopularityBaked into Health Score as 25% of the totalNot baked into Health Score
LifecycleNot modeledSix states: Active, Stable, Declining, Inert, Abandoned, Archived
Stable "done" librariesPenalized: low commits meant a low scoreLifecycle context added: a Stable classification signals low activity is intentional, but the Health Score formula still scores low-activity signals as low
Maintainer signalContributor count onlyResponsiveness, bus factor (curated plus observed), organizational diversity
SecurityOpenSSF Baseline pass/fail ratioOpen CVEs with severity weighting, security practices, OpenSSF Scorecard, dependency health, supply chain integrity
Missing dataReturned unavailable if any sub-score was absentBlocked sub-signals are imputed at the population median rate; full score requires ≥2 categories, 1 missing shows a partial indicator, ≥2 missing returns unavailable
Rating bandsExcellent / Healthy / Stable / Unsteady / CriticalExcellent / Healthy / Fair / Concerning / Critical

Why the original approach had gaps ​

The previous model had several structural problems:

  • Equal weighting ignored blast radius. A project with a single maintainer and a critical open CVE could score the same as a project with ten maintainers and a clean security record, if their activity levels were similar.
  • Popularity baked into health. A massively downloaded project with a compromised or absent maintainer appeared healthy because download counts inflated the score.
  • Stable libraries were penalized. A mature utility with no bugs, no CVEs, and no need for active development scored near Critical simply because it had few recent commits.
  • No lifecycle signal. The model could not distinguish "abandoned with a high score" from "active with a high score," a critical difference for stewardship and dependency risk.
  • Any missing sub-score returned unavailable. Projects on GitLab or Gerrit, or projects without package data, often could not be scored at all.