DEV Community

Alex Spinov
Alex Spinov

Posted on

7 JavaScript One-Liners That Replace Entire NPM Packages

Stop Installing Packages for Things JavaScript Already Does

Every npm install adds supply chain risk, bundle size, and complexity. Here are 7 cases where a single line of native JavaScript replaces a popular package.

1. UUID Generation (replaces uuid)

const id = crypto.randomUUID();
// "3b241101-e2bb-4d7a-8702-9e3c8a4f5b6a"
Enter fullscreen mode Exit fullscreen mode

Package: uuid — 30M+ weekly downloads, 7KB
Native since: Node 19+, all modern browsers

2. Deep Clone (replaces lodash.cloneDeep)

const clone = structuredClone(original);
Enter fullscreen mode Exit fullscreen mode

Package: lodash.cloneDeep — 10M+ weekly downloads
Native since: Node 17+, all modern browsers
Bonus: Handles circular references, Maps, Sets, Dates, RegExp

3. Array Grouping (replaces lodash.groupBy)

const grouped = Object.groupBy(users, user => user.role);
// { admin: [...], user: [...], moderator: [...] }
Enter fullscreen mode Exit fullscreen mode

Package: lodash.groupBy — 8M+ weekly downloads
Native since: Node 21+, Chrome 117+, Firefox 119+

4. Query String Parsing (replaces qs)

const params = Object.fromEntries(new URLSearchParams("name=john&age=30"));
// { name: "john", age: "30" }
Enter fullscreen mode Exit fullscreen mode

Package: qs — 65M+ weekly downloads, 30KB
Native since: forever (URLSearchParams is old)

5. Debounce (replaces lodash.debounce)

const debounce = (fn, ms) => { let t; return (...a) => { clearTimeout(t); t = setTimeout(() => fn(...a), ms); }; };
Enter fullscreen mode Exit fullscreen mode

Ok, it's a two-liner. But it's 1 line if you minify it, and it's 100 bytes vs 7KB for lodash.debounce.

6. Flatten Arrays (replaces array-flatten)

const flat = nested.flat(Infinity);
// [1, [2, [3, [4]]]] → [1, 2, 3, 4]
Enter fullscreen mode Exit fullscreen mode

Package: array-flatten — 25M+ weekly downloads
Native since: ES2019, Node 11+

7. Number Formatting (replaces numeral)

const formatted = new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" }).format(1234567.89);
// "$1,234,567.89"
Enter fullscreen mode Exit fullscreen mode

Package: numeral — 3M+ weekly downloads, 60KB, unmaintained since 2017
Native since: forever. Intl handles currencies, percentages, compact notation, units.

The Real Cost of NPM Packages

1 unnecessary package = 
  + 1 supply chain attack vector
  + 1 thing that can break on next Node version
  + 1 thing that needs security updates
  + X KB added to your bundle
  + Y seconds added to npm install
Enter fullscreen mode Exit fullscreen mode

After the event-stream incident, the ua-parser-js hack, and the colors.js sabotage — minimizing dependencies isn't paranoia, it's engineering.

When to Still Use the Package

  • uuid: If you need v1/v3/v5 UUIDs (not just v4)
  • qs: If you need nested object serialization
  • lodash: If you need 5+ utilities from it (import specific functions)

For everything else — check MDN first, npm second.


What packages have you replaced with native APIs? Would love to hear your list.


More from me: 10 Dev Tools I Use Daily | 77 Scrapers on a Schedule | 150+ Free APIs

Top comments (0)