Remove Unnecessary NPM Packages with eslint-plugin-depend

We don't need packages to handle basic JavaScript tasks

Trevor I. Lasn Trevor I. Lasn
· 4 min read
Building 0xinsider.com — the Bloomberg terminal for prediction markets.

The NPM ecosystem is cluttered with unnecessary packages like is-odd, is-even, is-number, and more. We don’t need this unnecessary clutter.

Ever heard of the is-number? It’s an infamous NPM package that simply checks if a value is a number or not.

import isNumber from 'is-number';

I checked out the is-number package and here’s what it actually does.

module.exports = function(num) {
if (typeof num === 'number') {
return num - num === 0;
}
if (typeof num === 'string' && num.trim() !== '') {
return Number.isFinite ? Number.isFinite(+num) : isFinite(+num);
}
return false;
};

If only there were a built-in method to check if something is a number. Oh, wait… there is.

const number = 5;
typeof number === "number" && Number.isFinite(number); // true
  1. typeof num === ‘number’: Verifies that num is of the type “number”. This excludes other data types like strings, objects, etc.

  2. Number.isFinite(num): Ensures that num is a finite number, meaning it is not NaN, Infinity, or -Infinity.

Infinity, -Infinity, and NaN are all considered numbers in JavaScript, so typeof returns ‘number’ for each of them. Thus, these statements are true.

typeof Infinity === 'number'; // true
typeof -Infinity === 'number'; // true
typeof NaN === 'number'; // true

While typeof returns true for each of these values, Number.isFinite returns false because Infinity, -Infinity, and NaN are not finite numbers. Therefore, the combined expressions using && evaluate to false.

typeof Infinity === "number" && Number.isFinite(Infinity); // false
typeof -Infinity === "number" && Number.isFinite(-Infinity); // false
typeof NaN === "number" && Number.isFinite(NaN); // false

Both 5 and -5 are valid, finite numbers, so both expressions are true.

typeof 5 === "number" && Number.isFinite(5); //true
typeof -5 === "number" && Number.isFinite(-5); // true

Moving back to rubbish packages. How on earth does is-number have 68,049,915 weekly downloads?

I guess it’s likely because is-number is a dependency for many popular libraries and frameworks. Even if you’re not using it directly, it could be included in your project through another package that relies on it.

left-pad package

In 2016, the left-pad package was unexpectedly removed from the npm registry, causing widespread disruption in the JavaScript ecosystem.

Many projects depended on this tiny package for a simple string padding function.

Its removal led to broken builds and errors in numerous projects, highlighting the risks of relying on overly granular or unnecessary dependencies.

The incident underscored the importance of using native functionality whenever possible to avoid such issues. See the left-pad incident wikipedia page.

import leftpad from 'left-pad';

Since String.prototype.padStart is a standard part of modern JavaScript, there’s no need to rely on an additional package for this.

"left-pad" should be replaced with native functionality. You can instead use String.prototype.padStart.
Read more here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStarteslintdepend/ban-dependencies

eslint-plugin-depend

This ESLint plugin detects redundant packages and suggests more efficient alternatives.

import isNumber from 'is-number';

Would trigger a notification inside the code editor/IDE

"is-number" should be replaced with inline/local logic. Use typeof v === "number" || (typeof v === "string" && Number.isFinite(+v)) eslint depend/ban-dependencies

Installing


npm i -D eslint-plugin-depend

eslint.config.js

import * as depend from 'eslint-plugin-depend';
export default [
depend.configs['flat/recommended']
];

You may choose a preset list of dependencies (or none). The following are available:

  1. microutilities: micro utilities (e.g. one liners)
  2. native: redundant packages with native equivalents
  3. preferred: an opinionated list of packages with better maintained and lighter alternatives
Terminal window
{
"rules": {
"depend/ban-dependencies": ["error", {
"presets": ["native"]
}]
}
}

The default is [‘native’, ‘microutilities’, ‘preferred’].

modules: You may specify your own list of packages which will be disallowed in code.

Terminal window
{
"rules": {
"depend/ban-dependencies": ["error", {
"modules": ["im-a-banned-package"]
}]
}
}

Putting it together

import * as depend from 'eslint-plugin-depend';
export default [
depend.configs['flat/recommended'],
{
rules: {
"depend/ban-dependencies": ["error", {
presets: ["native"],
modules: ["im-a-banned-package"]
}]
}
}
];

Trim the fat, clear out the clutter, and let your code breathe. Your users will thank you for it.


Trevor I. Lasn

Building 0xinsider.com — the Bloomberg terminal for prediction markets. Product engineer based in Tartu, Estonia, building and shipping for over a decade.


Found this article helpful? You might enjoy my free newsletter. I share dev tips and insights to help you grow your coding skills and advance your tech career.


Related Articles

Check out these related articles that might be useful for you. They cover similar topics and provide additional insights.

Webdev
3 min read

CVE-2025-29927 - Next.js Middleware Bypass Explained In Simple Terms

The vulnerability skips Next.js middleware security checks by adding a single HTTP header

Apr 6, 2025
Read article
Webdev
4 min read

CSS :interest-source and :interest-target Pseudo-Classes

Style connected UI elements with CSS pseudo-classes that respond to user interest. Interactive examples showing tooltips, forms, and navigation without JavaScript.

Nov 12, 2025
Read article
Webdev
3 min read

::details-content: style expandable content without wrapper divs

The ::details-content pseudo-element lets you style the expandable content of details elements separately from the summary, no divs needed.

Nov 11, 2025
Read article
Webdev
6 min read

How I Use Vercel BotID to Stop Bots on Auth Endpoints

BotID verifies browser challenges before proxying to the backend. Here's how I set it up in Next.js 16.

Feb 16, 2026
Read article
Webdev
5 min read

Add Auth to Astro 5 with Clerk in 5 Minutes

The simplest setup for adding Clerk authentication to your Astro project, with minimal code

Dec 18, 2024
Read article
Webdev
6 min read

Micro Frontends: The LEGO Approach to Web Development

Explore the concept of micro frontends in web development, understand their benefits, and learn when this architectural approach is most effective for building scalable applications.

Oct 2, 2024
Read article
Webdev
5 min read

Mermaid.js — Create Charts and Diagrams With Markdown-like Syntax

Mermaid.js is a simple markdown-like script language for generating charts from text via JavaScript

Oct 30, 2019
Read article
Webdev
5 min read

WebAssembly (Wasm): When (and When Not) to Use It

Understanding the real use cases for WebAssembly beyond the performance hype

Nov 25, 2024
Read article
Webdev
3 min read

CSS ::target-text for Text Highlighting

A look at how browsers can highlight text fragments using CSS ::target-text, making text sharing and navigation more user-friendly

Dec 17, 2024
Read article

This article was originally published on https://www.trevorlasn.com/blog/eslint-plugin-depend. It was written by a human and polished using grammar tools for clarity.