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.
See the live comparison
View fastify vs. express on PkgPulse →