DEV Community

Freshdeps
Freshdeps

Posted on • Originally published at freshdeps.vercel.app

Your AI keeps recommending these dead npm/PyPI packages — here is the exact migration for each

Your build broke. Your AI told you to install a dead package.

You asked Claude, Cursor, or Copilot for a library. It gave you a confident answer. You npm installed (or pip installed) it — and now your build throws a deprecation warning, a peer-dependency error, or just fails outright. You search the package name. You land here.

This is a reference. Find your package in the tables below, copy the exact replacement and the one-line change. Every entry is hand-verified — there are no inferred or AI-guessed replacements here, which is the entire point: the thing that broke your build was a confident guess.

Why your AI keeps doing this

An LLM's package knowledge is frozen at its training cutoff — typically 6–18 months stale by the time you use it. In that window a library gets deprecated, hands off maintenance, archives its repo, or picks up a CVE. The model has no way to know. A newer or bigger model does not fix this; it just moves the stale cutoff forward a few months. Sonatype's 2026 analysis put LLM dependency-upgrade hallucination near 27% across tens of thousands of enterprise upgrades — this is the default failure mode of AI-assisted dependency work, not an edge case.

The only real fix is a live lookup at recommendation time. The packages below are the ones stale agents recommend most often. Each package name links to a live freshness verdict (npm/PyPI registry + GitHub API + OSV.dev, computed at request time) so you can confirm it is still dead before trusting this page.

npm — dead package → exact migration

Dead package Replace with Why it's dead + the exact change
request got request is fully deprecated (no longer maintained since 2020).
const got = require('got'); const body = await got(url).text(); // replaces request(url, cb); npm i got
moment dayjs moment is in maintenance mode; dayjs is a 2KB modern alternative.
dayjs().format('YYYY-MM-DD') // dayjs is API-compatible for common ops; npm i dayjs
node-sass sass node-sass is deprecated; the Dart-based 'sass' is the official path.
npm rm node-sass && npm i -D sass // Dart Sass is a drop-in for most build setups
querystring URLSearchParams (built-in) Node's legacy querystring is deprecated; use the WHATWG URLSearchParams.
new URLSearchParams({a:'1'}).toString() // replaces querystring.stringify; built-in, no dep
colors chalk colors had a sabotage incident (2022); chalk is the maintained standard.
const chalk = require('chalk'); chalk.red('x') // replaces require('colors'); 'x'.red; npm i chalk
faker @faker-js/faker the original faker was sabotaged/unpublished; @faker-js/faker is the community fork.
const { faker } = require('@faker-js/faker'); faker.person.fullName() // npm i @faker-js/faker
left-pad String.prototype.padStart (built-in) native string padding makes the dependency unnecessary.
str.padStart(5, '0') // native, replaces leftPad(str,5,'0'); no dependency needed
tslint eslint TSLint was deprecated in 2019 in favor of typescript-eslint.
npm rm tslint && npm i -D eslint typescript-eslint && npx eslint --init
istanbul nyc the istanbul package is superseded by nyc / c8.
npx nyc <your-test-cmd> // replaces 'istanbul cover'; npm i -D nyc
gulp-util fancy-log + plugin-error gulp-util was deprecated and split into smaller modules.
require('fancy-log') for logging, require('plugin-error') for PluginError // gulp-util was split
babel-core @babel/core Babel 6 packages are unmaintained; use the scoped @babel/* (v7+).
npm rm babel-core babel-cli && npm i -D @babel/core @babel/cli; rename presets to @babel/preset-*
bower npm / yarn Bower is deprecated; modern bundlers use npm/yarn package resolution.
move bower.json deps into package.json; use 'npm install <pkg>' instead of 'bower install'
tape vitest tape is minimally maintained; vitest is a fast modern test runner.
npm i -D vitest; replace test('x',t=>{t.equal(a,b)}) with test('x',()=>{expect(a).toBe(b)})
nodemon node --watch (built-in) Node 18+ ships a native --watch mode for most dev-restart needs.
node --watch app.js // replaces 'nodemon app.js' on Node 18+
enzyme @testing-library/react enzyme is abandoned (last release 2019; no React 18/19 adapter ever shipped).
npm rm enzyme enzyme-adapter-react-16 && npm i -D @testing-library/react; replace shallow(<C/>) / wrapper.find('.x') with render(<C/>) + screen.getByRole/getByText
react-scripts Vite Create React App was officially deprecated by the React team (Feb 2025); react-scripts has no active maintainers.
npm rm react-scripts && npm i -D vite @vitejs/plugin-react; move index.html to project root, add vite.config.js, scripts: dev='vite', build='vite build'
node-uuid uuid node-uuid is deprecated; the registry redirects you to 'uuid'.
npm rm node-uuid && npm i uuid; const { v4: uuidv4 } = require('uuid'); uuidv4() // replaces require('node-uuid').v4()
request-promise got request-promise is deprecated (it extends the dead request package).
npm rm request-promise && npm i got; const got = require('got'); const body = await got(url).text() // replaces rp(url)
request-promise-native got request-promise-native is deprecated (it extends the dead request package).
npm rm request-promise-native && npm i got; const got = require('got'); const json = await got(url).json() // replaces rp(url)
jade pug jade was renamed to pug; the jade package is deprecated.
npm rm jade && npm i pug; require('pug').renderFile(path, locals) // identical template syntax, replaces require('jade')
coffee-script coffeescript the npm package was renamed to 'coffeescript' (no hyphen); coffee-script is deprecated.
npm rm coffee-script && npm i coffeescript; require('coffeescript/register') // same API, new package name
phantomjs-prebuilt playwright phantomjs-prebuilt is deprecated; PhantomJS development is suspended.
npm rm phantomjs-prebuilt && npm i -D playwright; const { chromium } = require('playwright'); const browser = await chromium.launch() // headless Chromium replaces PhantomJS
protractor @playwright/test Protractor is deprecated and reached end-of-life (Summer 2023).
npm rm protractor && npm i -D @playwright/test; rewrite element(by.css('x')) as page.locator('x'); npx playwright test
karma vitest Karma is deprecated (Angular 20 deprecated it; removal in Angular 22).
npm rm karma karma-* && npm i -D vitest jsdom; replace karma.conf.js with vitest config (environment: 'jsdom'); npx vitest
q native Promises / async-await the q package is deprecated; native Promises cover its API.
Q.defer() -> new Promise((resolve,reject)=>{}); Q.all(x) -> Promise.all(x); Q(v) -> Promise.resolve(v); no dependency needed
bluebird native Promises bluebird is unmaintained (last release 2019); native V8 Promises are now faster and standard.
Promise.promisify(fn) -> require('util').promisify(fn); Promise.map(arr,fn) -> Promise.all(arr.map(fn)); drop the dependency
babel-preset-es2015 @babel/preset-env babel-preset-es2015 is deprecated; @babel/preset-env supersedes the year-based presets.
npm rm babel-preset-es2015 && npm i -D @babel/preset-env; in .babelrc replace presets:['es2015'] with presets:['@babel/preset-env']
eslint-loader eslint-webpack-plugin eslint-loader is deprecated in favor of eslint-webpack-plugin.
npm rm eslint-loader && npm i -D eslint-webpack-plugin; remove the eslint-loader rule, add new ESLintPlugin() to webpack plugins[]

PyPI — dead package → exact migration

Dead package Replace with Why it's dead + the exact change
nose pytest nose is unmaintained (dead since ~2015); pytest is the standard.
pip install pytest && pytest // replaces nosetests; test discovery is automatic
nose2 pytest nose2 sees little activity; pytest is the de-facto Python test runner.
pip install pytest && pytest // test discovery is automatic
python-dateutil datetime / zoneinfo (stdlib) Python 3.9+ stdlib zoneinfo covers most dateutil timezone use.
from zoneinfo import ZoneInfo # py3.9+ stdlib, replaces dateutil.tz for most tz use
flask-restful fastapi flask-restful is largely dormant; FastAPI is the modern async API framework.
pip install fastapi uvicorn; rewrite Resource classes as FastAPI path operations
distribute setuptools distribute was merged back into setuptools years ago.
remove distribute; modern setuptools already provides its functionality
requests-oauthlib authlib authlib is more actively maintained for modern OAuth flows.
pip install authlib; use authlib.integrations.requests_client.OAuth2Session
pycrypto pycryptodome pycrypto is dead (last release 2014) and has unpatched CVEs; pycryptodome is the maintained drop-in.
pip uninstall pycrypto && pip install pycryptodome; same 'from Crypto.Cipher import AES' imports work unchanged
mysql-python mysqlclient MySQL-python is dead (Python 2 only, last release 2014); mysqlclient is the maintained fork.
pip install mysqlclient; import MySQLdb still works (mysqlclient keeps the MySQLdb module name)
pil Pillow PIL is dead (last release 2009, Python 2 only); Pillow is the maintained fork.
pip uninstall PIL && pip install Pillow; 'from PIL import Image' keeps working (Pillow ships the PIL namespace)
beautifulsoup beautifulsoup4 the bare 'BeautifulSoup' package is BeautifulSoup 3 — unmaintained; use beautifulsoup4.
pip uninstall BeautifulSoup && pip install beautifulsoup4; 'from bs4 import BeautifulSoup' (was 'from BeautifulSoup import BeautifulSoup')
sklearn scikit-learn the 'sklearn' PyPI package is a deprecated shim (it now errors on install); install scikit-learn.
pip uninstall sklearn && pip install scikit-learn; the import 'import sklearn' is unchanged — only the install name differs
enum34 enum (stdlib) enum34 is a Python 3.4 backport; enum has been in the stdlib since Python 3.4.
pip uninstall enum34; 'from enum import Enum' from the standard library — no dependency needed on Python 3
futures concurrent.futures (stdlib) the 'futures' package is a Python 2 backport; concurrent.futures is stdlib on Python 3.2+.
pip uninstall futures; 'from concurrent.futures import ThreadPoolExecutor' from the stdlib — no dependency needed
scikits-learn scikit-learn scikits.learn was renamed to scikit-learn years ago (last release 2011).
pip uninstall scikits.learn && pip install scikit-learn; 'from sklearn import ...' is the import in both
fabric3 fabric fabric3 was a stop-gap Py3 fork; modern fabric (2.x+) supports Python 3 natively.
pip uninstall fabric3 && pip install fabric; rewrite fabfile run()/local() using the Connection/task API of Fabric 2+
pathlib pathlib (stdlib) the PyPI pathlib backport is obsolete and breaks modern builds; pathlib is stdlib since Python 3.4.
pip uninstall pathlib; 'from pathlib import Path' from the standard library — remove it from requirements entirely
pep8 pycodestyle pep8 was renamed to pycodestyle; the pep8 package is deprecated.
pip uninstall pep8 && pip install pycodestyle; run 'pycodestyle <path>' (same checks, new command name)
nose-parameterized parameterized nose-parameterized was renamed to 'parameterized' and is deprecated.
pip uninstall nose-parameterized && pip install parameterized; 'from parameterized import parameterized' (was 'from nose_parameterized import parameterized')

Make your agent stop recommending these

Reading a table after the build breaks is the slow path. The fast path is the agent checking before it recommends. The same hand-verified corpus above sits behind a live API and a one-tool MCP server:

  • JSON API, no account: GET https://freshdeps.vercel.app/api/verdict?ecosystem=npm&package=node-sass&ref=devto-deadpkg
  • MCP server — one paste into your client config (Claude Desktop, Cursor, …), no account, no key:
{"mcpServers":{"freshdeps":{"command":"npx","args":["-y","github:SolvoHQ/freshdeps-mcp"]}}}
Enter fullscreen mode Exit fullscreen mode

With a project rule like "before recommending or adding any npm/PyPI dependency, call check_dependency_freshness and don't recommend anything that comes back abandoned", this table stops being something you ever need to open.

Notes & limits

  • npm + PyPI only. The corpus is curated by hand and never inferred — if a package is not in the tables above, this page makes no claim about it.
  • "Dead" means deprecated, unmaintained, archived, renamed, or superseded by the stdlib — the migration cell tells you which.
  • Live verdicts are computed per request; under unauthenticated GitHub rate limits a verdict can come back registry-only rather than failing.
  • Found one that's wrong, or a common dead package that's missing? That is the single most useful feedback — this corpus only improves with disagreement.

Source / MCP repo: https://github.com/SolvoHQ/freshdeps-mcp

Top comments (1)

Collapse
 
harjjotsinghh profile image
Harjot Singh

this is a solid reminder about the risks of relying on AI for package recommendations. it’s crucial to verify dependencies, especially when they can lead to broken builds. on a different note, if you're looking to deploy apps quickly, check out Moonshift - you can get a full next.js + postgres + auth build live in about 7 minutes, and you own the code. happy to offer a free run if you want to give it a shot.