Skip to main content

The Average Lifespan of an npm Package

·PkgPulse Team

TL;DR

The median npm package last receives an update within 18 months of being published — after that, it's likely abandoned. The top 1% of packages survive and thrive for 10+ years. The other 99% either solve a very narrow problem (no updates needed) or get abandoned when maintainer interest wanes. The survival predictors: corporate backing, multiple active contributors, or solving a genuinely evergreen problem. Popularity alone doesn't predict survival.

Key Takeaways

  • 50% of packages: last update within 18 months of publish
  • Top 1%: 10+ year packages (React, lodash, Express, jQuery)
  • Corporate backing is the strongest survival predictor
  • "Solved" packages (uuid, semver) survive long with minimal maintenance
  • The danger zone: packages 2-5 years old with a single maintainer

The npm Package Lifecycle

Phase 1: Launch (0-3 months)
→ Author publishes to solve a specific problem
→ If it gets traction: stars accumulate, issues filed
→ Most packages die here: no traction, no motivation to maintain
→ ~50% of packages: never updated after initial publish

Phase 2: Early maintenance (3-18 months)
→ Author still motivated: responding to issues, shipping features
→ Community grows if useful
→ ~30% of packages: last updated in this window
→ After 18 months, the probability of another update drops significantly

Phase 3: Survival or stagnation (18 months - 3 years)
→ Survivors: have user community, maintainer still invested, or corporate backing
→ Stagnators: author moved on, or problem was so well-solved no changes needed
→ ~10% of npm packages survive to 3 years with meaningful activity

Phase 4: Long-term maintenance (3-10+ years)
→ The packages that become infrastructure
→ Changes slow dramatically (intentional stability)
→ ~1% of npm packages
→ These are the lodash/axios/Express of the ecosystem

What Predicts Long-Term Survival

Survival analysis of npm packages:

Strongest predictors of 5+ year active maintenance:

1. Corporate backing (3x survival rate vs solo):
→ React (Meta), Angular (Google), Webpack (Bytedance), Express (OpenJS Foundation)
→ Companies have financial incentive to maintain their tooling investments
→ Employee time allocated to maintenance explicitly

2. Multiple active contributors (2x survival rate):
→ Single maintainer: one life event ends the project
→ 3+ active contributors: resilient to any individual's departure
→ Contributor growth signals expanding community investment

3. Solving an evergreen problem:
→ UUID generation: will always need this
→ HTTP requests: will always need this
→ Date parsing: will always need this
→ Contrast with: "CSS-in-JS for a specific React pattern" (problem might not exist in 3 years)

4. Growing downloads (not just large):
→ Flat downloads: the problem is solved, the package is stable
→ Growing downloads: new users arriving = new value = motivation to maintain

5. Clear project scope:
→ Narrow scope = fewer breaking changes needed
→ Lodash: does utility functions (solved)
→ "Full-stack framework": scope creep → eventual abandonment

Package Categories by Typical Lifespan

Long-lived categories (10+ year packages common):
→ Utility libraries: lodash, underscore, ramda
→ HTTP servers: express, koa, fastify
→ Test runners: jest (10+ years), mocha (12+ years)
→ Build tools: webpack (11+ years), Rollup (8+ years)
→ Core utilities: semver, mime, bytes

Medium-lived categories (3-8 years typical):
→ Frontend frameworks: React (10+), Vue (9+), but many alternatives
→ ORMs: Prisma (7+), Mongoose (13+)
→ Authentication: passport (12+), but smaller auth packages churn
→ Bundler plugins: specific to bundler ecosystem lifecycle

Short-lived categories (<3 years common):
→ CSS-in-JS: fast churn, paradigm shifts
→ "Wrapper" packages: wraps another API, dies when API changes
→ Scaffold tools: create-react-app, create-vue, etc. (replaced by Vite)
→ Highly specific plugins: for specific frameworks/tools
→ AI utility packages: category too new to have established survivors

The warning sign:
→ A package in a "short-lived" category that's 3+ years old with no recent activity
→ High probability it's abandoned, problem was solved, or the category moved on

The 1000 Days Rule

Informal observation from package maintainers:

A package's maintenance commitment drops significantly after ~1000 days (2.7 years)
if it hasn't reached "institutional" status by then.

Why 1000 days:
→ The "exciting new project" phase: ~6 months
→ "Maintaining what I built" phase: ~18 months
→ "Maintaining what users need but I don't use daily": ~24+ months (harder)
→ After 1000 days: either the project runs itself, has a team, or the author moves on

Evidence for this pattern:
→ Look at GitHub commit graphs for mid-tier npm packages
→ Majority have a "high activity period" followed by cliff
→ The cliff often happens 18-30 months after launch

What gets packages past the 1000-day barrier:
1. Corporate adoption: somebody's job is now to maintain it
2. Community takeover: original author transfers to community org
3. Problem maturity: "solved" packages don't need active maintenance
4. Financial support: open collective, GitHub sponsors, sponsors program

Historical Package Graveyard (Famous Examples)

# Packages that died despite early success:

# Bower (frontend package manager):
# Launch: 2012
# Peak: 2014-2015 (most popular frontend package manager)
# Death: 2017 (deprecated by maintainers, npm took over)
# Lifespan: ~5 years, but last 3 in maintenance mode

# Grunt (build system):
# Launch: 2012
# Peak: 2013-2015
# Decline: Gulp (2013), then Webpack/Rollup (2015+) → irrelevant
# Current: still alive but ~95% smaller install base

# Jasmine (testing):
# Launch: 2010
# Peak: 2011-2014 (before Jest)
# Decline: Jest dominance from 2016
# Current: actively maintained, used in AngularJS ecosystem

# CoffeeScript:
# Launch: 2010
# Peak: 2012-2015 (compiled JS before TypeScript)
# Decline: TypeScript released 2012, won by 2018
# Current: maintained but declining — a cautionary tale

# Jade/Pug (templating):
# Jade → Pug rename in 2016 (copyright issue)
# Still maintained, but HTML templates have given way to JSX/TSX

# The pattern: packages die when the problem they solve gets absorbed
# by a bigger ecosystem player (npm absorbed Bower, React absorbed templates)

How to Evaluate a Package's Survival Probability

# Quick survival probability assessment:

# 1. Age + activity:
npm view package-name time --json | jq 'to_entries | last | .value'
# Last publish date

# 2. Download trend:
# npmtrends.com/package-name → look at 1-year chart
# Flat or growing → healthy
# Declining rapidly → migration happening

# 3. Corporate vs solo:
npm view package-name --json | jq '.maintainers | length'
# > 1 maintainer = better
# Organization: npmjs.com/org/org-name → shows team

# 4. GitHub org vs personal:
npm view package-name --json | jq '.repository.url'
# github.com/some-org/package = org-backed (better)
# github.com/username/package = solo (watch for bus factor)

# 5. OpenJS or similar foundation:
# https://openjsf.org/projects/ — hosted projects have guaranteed continuity

# Risk matrix:
# Low risk: Corporate-backed, 3+ contributors, growing downloads
# Medium risk: Solo maintainer but active, growing project
# High risk: Solo maintainer, stagnant downloads, last activity 12+ months
# Very high risk: Stagnant, declining, single maintainer, no org transfer

Compare package health scores and maintenance data at PkgPulse.

Comments

Stay Updated

Get the latest package insights, npm trends, and tooling tips delivered to your inbox.