DEV Community

Cover image for 5 Underrated NPM Packages You’re Not Using (But Should Be)
Balraj Singh
Balraj Singh

Posted on

5 Underrated NPM Packages You’re Not Using (But Should Be)

The world of NPM is massive. Over 2 million packages, and yet, most developers end up using the same 20-30 over and over again.

React, Lodash, Express. The usual suspects.

But what about the hidden gems? The ones that could make your workflow easier, cleaner, and smarter?

Here are five underrated NPM packages that deserve more attention.

1. date-fns-tz

Time zones are annoying. This makes them less so.

If you’ve ever scheduled an event across time zones, you know how quickly things get messy. Moment.js? Bloated. Manually handling offsets? A disaster waiting to happen.

Enter date-fns-tz.

Why it deserves more love:

  • Built on date-fns, so it’s modular and tree-shakable.
  • Does one thing well: time zone management.
  • No unnecessary overhead.

Where it helps:
When you’re building apps that handle scheduling for users in different time zones.

Example:

import { formatInTimeZone } from 'date-fns-tz';

const timeZone = 'America/New_York';
const date = new Date();

const formattedDate = formatInTimeZone(date, timeZone, 'yyyy-MM-dd HH:mm:ssXXX');
console.log(formattedDate); // 2024-11-25 10:00:00-05:00
Enter fullscreen mode Exit fullscreen mode

2. clsx

Writing messy className logic? Stop. Use this.

If you’ve written dynamic className logic in React, you’ve probably seen something like this:

const buttonClass = `btn ${isActive ? 'btn-active' : ''} ${isDisabled ? 'btn-disabled' : ''}`;
Enter fullscreen mode Exit fullscreen mode

It works. But it’s ugly.

Enter clsx. A tiny utility that makes class name logic elegant.

Why you need this:

  • Handles conditional logic, arrays, and objects effortlessly.
  • Automatically ignores falsy values.
  • Makes your UI code cleaner and more readable.

Example:

import clsx from 'clsx';

const isActive = true;
const isDisabled = false;

const buttonClass = clsx('btn', { 'btn-active': isActive, 'btn-disabled': isDisabled });
console.log(buttonClass); // "btn btn-active"
Enter fullscreen mode Exit fullscreen mode

3. ow

Validation that doesn’t make you want to quit coding.

If you’ve written input validation manually, you know it gets repetitive fast.

ow, by Sindre Sorhus, makes it simple and declarative.

Why it’s underrated:

  • TypeScript-friendly with strong error messages.
  • Expressive syntax that reads like English.
  • Handles complex validations in a single line.

Where it helps:
Validating API responses, CLI inputs, or function arguments.

Example:

import ow from 'ow';

const validateUser = (user) => {
  ow(user, ow.object.exactShape({
    name: ow.string.minLength(3),
    age: ow.number.integer.positive,
    email: ow.string.url,
  }));
};

validateUser({ name: 'John', age: 25, email: 'example@example.com' }); // Passes
Enter fullscreen mode Exit fullscreen mode

4. npm-check

Your node_modules is a mess. This fixes it.

Have you ever wondered:

  • Which dependencies are outdated?
  • Which ones are unused?
  • Which ones you accidentally forgot to install?

npm-check gives you an interactive way to clean things up.

Why it’s useful:

  • Finds outdated, unused, or missing dependencies.
  • Works interactively, so you can update/uninstall with a keystroke.
  • Works with both local and global packages.

Example:

npx npm-check
Enter fullscreen mode Exit fullscreen mode

Run that command, and you’ll get a nice interactive list of dependencies with options to update or remove them.

5. log-symbols

Make your CLI logs actually readable.

Ever built a CLI tool and thought, this looks so plain?

log-symbols adds intuitive icons (✅ ❌ ⚠️) to your logs, making them clearer at a glance.

Why you should use it:

  • Gives instant visual feedback in the terminal.
  • Works across macOS, Linux, and Windows.
  • Small but powerful.

Example:

import logSymbols from 'log-symbols';

console.log(logSymbols.success, 'Build completed successfully!');
console.log(logSymbols.error, 'Failed to connect to the database.');
console.log(logSymbols.warning, 'Using default configuration.');
Enter fullscreen mode Exit fullscreen mode

Don’t just use what’s popular. Use what makes your life easier.

The next time you find yourself repeating code or struggling with a common problem, take a detour into the lesser-known corners of NPM.

What’s your favorite underrated NPM package?

Top comments (2)

Collapse
 
tobyliu profile image
zhifu liu

I always use classnames to manage dynamic className logic in React. I compared clsx and classnames; their functions are similar, but clsx is smaller in size than classnames. I will use clsx instead of classnames in my next project. Thank you, this is helpful for me!

Collapse
 
keyru_nasirusman profile image
keyru Nasir Usman

Recently I abandoned one of my side projects because I couldn't solve timezone variations by using moment.js library. I will try date-fns-tz and see how it goes.