The 20 npm Packages Losing Downloads the Fastest 2026
TL;DR
Declining downloads are a leading indicator, not a death sentence — but they warrant investigation. Packages like Create React App, Moment.js, and Webpack haven't died; their download counts are still huge. But their growth curves are negative while alternatives accelerate. Knowing what's declining helps you avoid starting new projects on legacy tools and plan migrations before the ecosystem leaves you stranded.
Key Takeaways
- Create React App: -35% YoY — deprecated by React team, no security updates
- Webpack: -22% YoY — huge absolute downloads but Vite/Rspack eating share
- Moment.js: -28% YoY — replacements have better DX, smaller bundle
- Enzyme: -60% YoY — React 18 compatibility issues killed it
node-fetchv2: -45% YoY — Node.js nativefetchending the need
Category 1: Officially Deprecated
Official deprecation is the clearest signal in package health analysis. When a package's maintainers announce they recommend migrating away, several things typically follow: security vulnerabilities get reported but not patched, new framework compatibility issues go unresolved, and the package's download count becomes a measure of inertia rather than preference. The packages in this category still show substantial weekly downloads because they're embedded in legacy CI pipelines, old Google-indexed tutorials, and projects that haven't prioritized dependency cleanup. But no developer evaluating packages for a new project today would deliberately choose any of them.
The maintenance gap is what makes officially deprecated packages genuinely risky — not that they stop working immediately. Most continue functioning for years. The risk is that when a security vulnerability is disclosed (which happens to every major package eventually), there's no maintainer to patch it. Create React App has unpatched security advisories in its Webpack 4 and Babel dependencies that have been open for over two years. Any new project bootstrapped with CRA today inherits those vulnerabilities from the first npm install. The deprecated status also means no compatibility updates: CRA doesn't support React 18's concurrent features properly, and it never will.
1. Create React App — -35% YoY
# Status: DEPRECATED. Official React docs removed it.
# Last release: 2022. Security vulnerabilities unfixed.
# Current downloads: ~1.4M/week (was ~2.1M)
# Why still downloaded: legacy CI pipelines, old tutorials
# What to use instead:
# New projects: Vite + @vitejs/plugin-react
# Next.js: Next.js itself handles project setup
# Migration: 30-60 minutes (see CRA → Vite guide)
2. request (HTTP client) — -55% YoY
// Status: Deprecated by maintainer in 2020. No updates since.
// Security vulnerabilities with no patches.
// Current downloads: ~14M/week (legacy, not new installs)
// What to use instead:
// Fetch API (built-in Node 18+)
// axios (npm i axios)
// ky (npm i ky) — fetch-based, small
// undici (npm i undici) — Node.js native HTTP client
3. node-fetch v2 — -45% YoY
// Node 18+ has fetch built-in
// node-fetch v2 was CommonJS; the CJS/ESM transition made it awkward
// What happened:
// Node.js 18: fetch() global available without any npm install
// Most teams just deleted their node-fetch dependency
// If you need it for Node.js 16 (EOL): still fine
// Node.js 18+: just delete the package
const data = await fetch('https://api.example.com').then(r => r.json());
// No import needed in Node 18+
4. cross-fetch — -50% YoY
# Same story: native fetch makes polyfills obsolete
# Downloads: ~2M/week (from ~4M)
# Replacement: native fetch in Node 18+, undici for server-side specific needs
Category 2: Replaced by Better Tools
This category is more nuanced than official deprecation. Every package here still receives updates, has active maintainers, and continues working correctly for its intended use case. What changed is the competitive landscape: alternatives emerged offering meaningfully better developer experience, smaller bundle sizes, or architectural compatibility with patterns like React Server Components that newer packages were designed for from the start.
The key distinction from Category 1 is that migration decisions here are quality-of-life choices rather than security necessities. Keeping styled-components in a Next.js Pages Router application poses no CVE risk. But if you plan to adopt RSC, styled-components becomes an architectural blocker — it requires a React context API that Server Components intentionally don't provide. Understanding the specific reason a package is declining tells you how urgently migration matters for your project. A declining-but-maintained package used in a part of your stack that won't change doesn't need immediate action. A declining package that's incompatible with where your architecture is heading does.
The Enzyme situation illustrates a subtler failure mode: the package didn't get officially deprecated, it simply didn't receive a React 18 adapter that worked reliably. The React 18 concurrency model changed internal semantics enough that existing adapters broke in hard-to-diagnose ways. React Testing Library, which tests component behavior through the DOM rather than React internals, didn't have this problem — and gained the entire Enzyme user base as a result.
5. Moment.js — -28% YoY
// Status: Maintenance mode. Maintainers recommend migrating away.
// Downloads: ~14M/week (legacy — not going to zero anytime soon)
// The problem: 300KB bundle, mutable API, no tree shaking
// What teams are switching to:
// Day.js (2KB) — same API, drop-in for most use cases
// date-fns (functional, tree-shakeable)
// Luxon (Intl-based, modern API)
// Temporal (native, polyfill available)
6. Enzyme — -60% YoY
# React 18 compatibility issues that never got fixed
# No adapter for React 18 that works reliably
# Downloads: ~450K/week (from ~1.1M)
# What teams switched to:
npm install @testing-library/react
# Testing Library: tests behavior, not implementation
# Works perfectly with React 18 and beyond
7. Webpack (raw) — -22% YoY
# Webpack itself is declining; create-react-app was a huge source of webpack installs
# Direct webpack usage declining as teams migrate to Vite
# Downloads still ~20M/week (massive install base)
# But new projects rarely choose webpack
# What teams are choosing:
# Vite (new projects): 10x faster dev server
# Rspack (migration): webpack-compatible, 5-10x faster builds
# esbuild (simple builds): ultrafast, no framework overhead
8. express (legacy patterns) — -15% YoY overall
// Express itself still dominant but losing ground in new projects
// Specific express patterns declining:
// - body-parser (now built-in to Express 4.16+)
// - cookie-parser (Hono/Fastify handle this natively)
// - morgan (replaced by pino-http)
// Express downloads stable, but:
// Fastify growing +25% YoY
// Hono growing +195% YoY (edge/Bun use cases)
9. Redux (standalone) — -30% YoY
# Not Redux Toolkit — the raw "redux" package
# Most new installs are via @reduxjs/toolkit (which installs redux as a dep)
# Direct redux usage declining as teams choose:
# Zustand (simple stores)
# Jotai (atomic state)
# TanStack Query (server state)
# Valtio (proxy state)
10. styled-components — -40% YoY
# CSS-in-JS declining with RSC adoption
# styled-components doesn't work in React Server Components
# Downloads: ~5M/week (from ~8.3M)
# What teams are switching to:
# Tailwind CSS (utility-first, RSC compatible)
# CSS Modules (zero runtime, RSC compatible)
# Panda CSS (build-time CSS-in-JS, RSC compatible)
# Plain CSS with CSS custom properties
11. emotion/styled — -35% YoY
# Same issue as styled-components: RSC incompatibility
# Downloads declining across all @emotion/* packages
# Replacement: same as above — Tailwind, CSS Modules, Panda CSS
Category 3: Superseded by Built-ins
Node.js has been absorbing third-party package functionality into its core runtime across every major release since Node 10. Recursive mkdir landed in Node 10.12. Promisified file APIs came in Node 14. Native fetch arrived in Node 18. A built-in test runner shipped in Node 20. Each addition obsoletes a category of npm packages for developers on recent Node versions.
The transition is slower than the built-in availability would suggest. Developers don't automatically audit their dependencies when they upgrade Node — they start new projects without the old packages and remove them from existing projects when they happen to notice during a dependency review or security audit. The 35–55% YoY declines in this category represent the cohort of developers actively doing that cleanup. The full installed base is still catching up. If your project targets Node 18+, treating these packages as candidates for removal is one of the lowest-effort dependency hygiene wins available — no behavior changes, just delete a package.
12. lodash — -18% YoY
// Not dead, but slowly being replaced by native JS methods
// ES2022+ covers most common lodash operations:
// Array.from(), Object.entries(), structuredClone(), Array.at()
// Optional chaining ?. replaces _.get()
// Nullish coalescing ?? replaces _.defaultTo()
// Still useful for: deep clone (structuredClone is built-in but slower for some cases),
// complex data transformations, fp utilities
// Downloads: ~35M/week but trending down from peak of ~42M
13. util.promisify wrappers — varies
// Many packages exist solely to promisify Node.js callback APIs
// Node.js has been all-promise since Node 14
// Example: fs.promises.readFile() is built-in
// Packages like: `mz`, `graceful-fs`, `fs-extra` declining
// graceful-fs: -30% YoY as fs.promises covers the use cases
14. mkdirp — -40% YoY
// Creates directories recursively
// Built into Node.js since v10.12:
import { mkdirSync } from 'fs';
mkdirSync('a/b/c', { recursive: true }); // Built-in
// mkdirp downloads: declining as devs discover the built-in
15. rimraf — -35% YoY
// Recursive delete — rm -rf for Node.js
// Now built-in to Node.js 14.14+:
import { rmSync } from 'fs';
rmSync('./dist', { recursive: true, force: true });
// rimraf still useful for cross-platform scripts targeting Node 12
// New projects on Node 18+: just use built-in
Category 4: Hype Cycle Correction
Hype cycle packages aren't deprecated and haven't been superseded by built-ins. They're declining because the breadth of adoption exceeded the use cases where they genuinely excel. As the ecosystem matures and developers accumulate direct experience, adoption converges toward appropriate use cases and retreats from overextended ones.
GraphQL is the clearest current example. The "GraphQL for everything" wave peaked around 2020–2021. Teams adopted it for simple CRUD APIs where the schema overhead provided no value over a typed REST endpoint — and then migrated away when the maintenance cost became apparent. Apollo Client's declining downloads don't signal GraphQL's failure; they signal healthier, more selective adoption. The teams who actually benefit from GraphQL's data graph — federated microservices, complex cross-team API contracts, nested entity graphs — are keeping it. Teams that adopted it for hype are migrating to tRPC or TanStack Query for simpler type-safe access patterns.
The Gatsby decline tells a more specific story: a platform that benefited from strong early positioning, built a large ecosystem, and then stagnated when the competitive environment shifted faster than its development team could respond. Astro — which ships no JavaScript by default and has excellent SSG ergonomics — became Gatsby's primary beneficiary, growing 240% YoY while Gatsby fell 65%.
16. GraphQL clients (Apollo) — -20% YoY
# Apollo Client still dominant but growing more slowly
# The GraphQL-for-everything wave peaked
# tRPC offering type safety without GraphQL schema overhead
# Many teams: REST + TanStack Query for data fetching, no GraphQL
# apollo-client downloads: ~3.2M/week (from ~4M)
# urql also declining
# Growth going to: tRPC, TanStack Query direct API calls
17. firebase SDK — -15% YoY
# Firebase v9 modular SDK slower to adopt than expected
# Many teams switching to: Supabase (open source Firebase alternative)
# Supabase download growth: +180% YoY
# firebase downloads: ~2.1M/week (from ~2.5M)
18. Gatsby — -65% YoY
# Gatsby acquired by Netlify, then significant layoffs, then stagnation
# Downloads: ~180K/week (from ~510K)
# Replacement: Next.js, Astro, SvelteKit for SSG use cases
# Astro growing: +240% YoY as Gatsby's primary beneficiary
19. Nuxt 2 — -80% YoY
# Nuxt 2 (EOL Jan 2024) losing to Nuxt 3
# Nuxt 2 downloads collapsing as teams upgrade
# Nuxt 3 growing strongly: +45% YoY
20. vue-cli — -70% YoY
# Deprecated in favor of create-vue (uses Vite under the hood)
# Downloads: ~170K/week (from ~570K)
# Replacement:
npm create vue@latest # Uses Vite, TypeScript-first
How to Check If a Package Is Declining
# 1. npm trends (visual)
# Open: npmtrends.com/package-name
# Look at 1-year and 2-year chart
# 2. PkgPulse (health score + trend)
# Open: pkgpulse.com/compare/package-a-vs-package-b
# Health score factors in download trends
# 3. npm registry directly
npm view package-name time # Release history
npm view package-name --json | jq '.time | keys[-5:]' # Last 5 releases
# 4. GitHub signals
# Issues: are they being closed or piling up?
# Last commit date
# README: does it say "deprecated", "maintenance mode"?
# Red flags:
# ❌ Last release 18+ months ago (for active libraries)
# ❌ Official "use X instead" in README
# ❌ Maintainer last active 1+ year ago
# ❌ Security advisories with no response
# ❌ React 18 / Node 20 issues open for months
Reading the Download Chart: Five Patterns to Recognize
npm download charts look deceptively simple — a line going up or down. But the shape and context of the decline tells you more than the percentage change alone. Recognizing which pattern you're looking at determines whether your response is "urgent migration," "gradual roadmap item," or "no action needed."
Pattern 1: The Hockey Stick Break. A package growing steadily for years, then flattening and inverting around a specific date. This is the Create React App pattern. It indicates a defined triggering event — an official deprecation announcement, a major competitor reaching feature parity, or a platform shift like RSC going mainstream. The decline accelerates as word spreads through the developer community, and the inflection point is almost always traceable to a specific announcement in the git history or on the React team's blog. When you see this pattern, identifying the triggering event tells you how urgently you need to migrate: an official deprecation with no security patches is more urgent than a competitor winning new projects while your existing usage remains functional.
Pattern 2: The Slow Erosion. Downloads declining 10–20% per year across multiple years without a sharp break. This is the Lodash pattern: native JavaScript absorbed Lodash use cases incrementally across ES2020, ES2021, and ES2022, and each language feature converted a portion of the developer base. No urgency exists from the decline itself — Lodash remains well-maintained and appropriate for complex data transformations. But the trend signals that the package's role is narrowing from "default utility belt" to "specific situations where native alternatives fall short."
Pattern 3: The Platform Dependency. A package's decline correlates exactly with the adoption curve of a platform feature. node-fetch declined as Node 18 (shipping native fetch) reached LTS and then majority adoption. rimraf declined as Node 14.14's rmSync({ recursive: true }) became the obvious alternative. These declines are clean and predictable. Once a platform version reaches "safe baseline" status for your target environments, the corresponding packages become candidates for immediate removal — no behavior change required.
Pattern 4: The Category Collapse. An entire category of packages declining simultaneously, not one package losing to another. CSS-in-JS is a current example: styled-components, Emotion, JSS, and Glamour are all declining together. This signals an architectural shift rather than competitive displacement — the whole approach is losing to Tailwind and CSS Modules in RSC contexts. Category collapses require architectural thinking rather than package substitution. Switching from styled-components to Emotion doesn't solve the RSC incompatibility.
Pattern 5: The Legacy Long Tail. Downloads remain high but flat while the rest of the ecosystem grows, meaning the package's market share percentage falls even when absolute numbers hold steady. jQuery at tens of millions of weekly downloads isn't a health signal — it's historical artifact from legacy sites and WordPress installs. The request package at 14M/week has the same profile: overwhelmingly legacy pipelines and internal tooling that hasn't been touched in years, not active adoption by developers writing new code. High absolute download counts with flat or slowly declining trend lines deserve skepticism, not reassurance.
What Declining Downloads Signal About Ecosystem Health
A declining package isn't inherently a problem — it depends on why it's declining. Three patterns: First, replacement by a better alternative is healthy ecosystem churn. Day.js replacing Moment.js, Vite replacing Webpack for new projects, Vitest replacing Jest — these declines indicate a functioning ecosystem that routes developers toward better tools. The declining package is still maintained (in most cases) for existing users; new users make better choices. Second, deprecation without maintenance is a security and stability risk. Packages where the maintainer has stopped responding to security issues while downloads remain high (because they're locked into legacy systems) create compounding risk. The downloads aren't new adoption; they're sunk-cost dependencies that will eventually need to be extracted. Third, platform-driven obsolescence happens when language features or platform capabilities make a package unnecessary. mkdirp, rimraf, node-fetch, and cross-fetch are declining because Node.js built the functionality into the core runtime. This is the cleanest form of obsolescence — no security risk, no maintenance concern, just an unnecessary dependency. The health signal: when a package's README links to a replacement, the decline is planned and safe to follow. When a package is declining because its competitors are better but the maintainer continues updating it, you have a choice rather than a mandate. When a package is declining AND has open security issues AND has no maintainer activity, that's the urgent case for migration.
Migration Stories: Where Teams Actually Went
The "use X instead" recommendation is easy to give; the migration experience varies. Here's what teams actually encountered when migrating away from the declining packages: Create React App → Vite: The most commonly reported friction was Webpack-specific babel plugins that had no direct Vite equivalent. Teams using custom Babel transforms for CSS modules, image imports, or SVG components needed to find Vite plugin equivalents. Most found equivalents within 30 minutes; a few Babel transforms had no equivalent and required code changes. Timeline: 2-4 hours for a typical CRA project. Moment.js → Day.js/date-fns: The mutation behavior difference (described in the "Why Developers Are Abandoning Moment.js" article) caught teams that didn't have comprehensive test coverage. Automated find-replace worked for 80%+ of cases; the remaining 20% required reviewing mutation-dependent patterns manually. Teams with good test coverage completed in 1-2 hours; teams without tests took 4-8 hours including manual verification. styled-components → Tailwind: The hardest migration of the group. Rebuilding styled-components API (dynamic props, theme tokens, keyframes) in Tailwind CSS requires either a significant refactor (using Tailwind's config for colors/spacing) or adopting a CSS variable approach that preserves the dynamic styling. Teams reported 2-5 days for a medium-sized application. The ROI is real (RSC compatibility, build performance), but the migration is work.
Webpack → Vite is the highest-volume migration case in 2026, driven by teams finally dealing with Webpack 4 or 5 setups that have accumulated complexity over years. The challenge isn't Vite's configuration — it's plugin equivalence. Every Webpack loader has a Vite plugin equivalent, but the mapping isn't always one-to-one, and a few niche plugins don't have Vite versions yet. Teams using standard configurations (TypeScript + React + CSS Modules) typically complete the migration in half a day. Teams with custom Webpack chains — module federation, custom SVG transforms with nonstandard SVGR options, legacy browser polyfills via babel-loader — spend 2–3 days identifying and testing equivalents. One commonly missed detail: Vite's development server imports as native ESM, so any dependency that ships only CommonJS will require configuration in optimizeDeps.include. Most major packages resolved their ESM story by 2025, but internal company packages written before the ESM transition sometimes need manual fixes before the migration can proceed.
The migration ROI is substantial enough that teams consistently report it was worth the friction. Dev server startup drops from 30–90 seconds (Webpack dev server with cold cache) to under 2 seconds. CI production build times improve less dramatically — 2–4x rather than 10x, because production builds always ran the full bundle — but the improvement compounds across every CI run. For teams that run CI hundreds of times per week, Vite's build speed translates directly into reduced CI cost.
Auditing Your Own Dependencies for Hidden Declines
Your project may have dependencies that are declining but haven't yet been flagged in your team's dependency review. A systematic audit takes 30 minutes and catches most cases: First, run npm outdated and look at the "Latest" vs "Current" gap. A package at v2.1.0 current when v7.0.0 is latest is often a sign of a package that evolved significantly while your project didn't upgrade. Major version gaps sometimes indicate a package that changed philosophy (jQuery 1 → 3, Lodash 3 → 4) or one where upgrading would require significant refactoring. Second, visit npmtrends.com for your top 10-15 direct dependencies. Look at the 2-year trend. Any package with a clearly negative slope and a growing alternative is worth reviewing. Third, check GitHub for packages over 24 months since last release. npm view package-name time shows the release history. Filter to packages that are actively used in your application (not just transitive dependencies). Fourth, run npm audit and look specifically at vulnerabilities with no upstream fix. These are the highest-risk packages — they have known vulnerabilities and the maintainer isn't patching them. These are the urgent cases. The output of this audit should be a prioritized list: packages with security vulnerabilities first, packages with actively-maintained better alternatives second, packages that are declining but not problematic third (future tech debt, not current risk).
Monitor package health and download trends for any npm package at PkgPulse.
See also: AVA vs Jest and 20 Fastest-Growing npm Packages in 2026 (Data-Backed), Which Categories Have the Most Package Churn?.
See the live comparison
View moment vs. date fns on PkgPulse →