Methodology: The Calculus of 'Deaditude'

An Empirical Analysis of Technological Relevance
7/4/2026

Abstract

This document outlines the rigorous mathematical and statistical models utilized to calculate the Deaditude Score of software technologies.

1. Introduction

Determining whether a technology is "dead" requires moving beyond subjective developer opinions, Reddit flamewars, and Hacker News echo chambers into empirical data analysis. Our engine aggregates multiple signals to compute a unified score so you don't have to rely on that one guy who says "X is dying" every week.

2. Data Sources

3. The Deaditude Formula

The core equation relies on a weighted average of normalized metric decay over time. Given a time $t$, the Deaditude $D(t)$ is expressed as:

D(t) = α(1 - Gv) + β(1 - Nv) + γ(Sv)

Where:
$G_v$ = Normalized GitHub Velocity
$N_v$ = Normalized NPM Velocity
$S_v$ = StackOverflow Despair Index (Unanswered Questions)

3.1 Mathematical Implementation (Code snippet)

In practice, our Python-based calculation engine adjusts these weights dynamically based on the age of the technology and normalises the variance based on data quality:

def calculate_deaditude_score(
    metrics: Dict[str, Dict[str, float]],
    tech_info: Optional[Dict[str, Any]] = None,
) -> Dict[str, Any]:
    tech_age = _get_tech_age(tech_info)
    weights = YOUNG_TECH_WEIGHTS if tech_age <= YOUNG_TECH_THRESHOLD else BASE_WEIGHTS

    eff_w: Dict[str, float] = {}
    sigmas: Dict[str, float] = {}
    explanations: list[str] = []

    # Effective weights & per-source σ
    for src, base_w in weights.items():
        m = metrics.get(src) or {}
        q = _quality(m)
        eff_w[src] = base_w * q
        sigmas[src] = _sigma_for_quality(q)

    # Renormalise
    total_w = sum(eff_w.values()) or 1.0
    for src in eff_w:
        eff_w[src] /= total_w

    # Weighted mean (0-10)
    overall = sum(
        eff_w[s] * metrics.get(s, {}).get("deaditude_score", 5.0) 
        for s in eff_w
    )
    adjusted_overall = _adjust_score_by_age(overall, tech_age)
    
    # ... calculates Confidence Interval and returns 0-100 score
    pct = adjusted_overall * 10
    return { "overall_score": round(pct, 1) }

3.2 Data Collection Example (GitHub)

We query the GitHub GraphQL API to fetch exact, high-fidelity metrics, defaulting gracefully to REST when rate limited:

def _calculate_deaditude(metrics: Dict[str, Any]) -> float:
    score = BASE_SCORE # Starts at neutral 5.0

    # Negative signals (penalize inactivity)
    commits_30d = metrics.get("commits_last_30d") or 0
    if commits_30d == COMMITS_NONE_THRESHOLD:
        score += COMMITS_NONE_PENALTY
    elif commits_30d < COMMITS_LOW_THRESHOLD:
        score += COMMITS_LOW_PENALTY

    pr_age = metrics.get("pr_age_metrics", {}).get("avg", 0) or 0
    if pr_age > PR_OLD_THRESHOLD:
        score += PR_OLD_PENALTY

    # Positive signals (reward popularity)
    stars = metrics.get("stars", 0)
    if stars > STARS_VERY_HIGH_THRESHOLD:
        score -= STARS_VERY_HIGH_BONUS

    return max(0, min(10, score))

4. Peer Review

All data points and snapshots are stored in our open-source repository and are subject to public scrutiny. Re-evaluations occur on a bi-weekly basis.