Overview

Prefer native JavaScript; add a utility library only for the few helpers the platform lacks: deep merge, debounce, throttle, and deep clone of values structuredClone rejects. Lodash 4.18.1 (April 2026) is still maintained. Importing it whole costs about 70 KB minified (about 25 KB gzipped), so import single functions from lodash-es or use es-toolkit, a smaller TypeScript-first library with a es-toolkit/compat layer for Lodash APIs.

Comparison

TaskNativeWhen a library still wins
Deep clonestructuredClone(obj)Values holding functions or DOM nodes (structuredClone throws); class instances lose their prototype
Flatten, last, findarr.flat(), arr.at(-1), arr.find()None
Safe accessa?.b?.c ?? fallbackDynamic string paths (_.get(obj, path))
Group byObject.groupBy(arr, fn), Map.groupByOlder runtimes
Unique[...new Set(arr)]_.uniqBy on keys
Deep mergeNone (spread is shallow)_.merge, es-toolkit merge
Debounce, throttleNone_.debounce, _.throttle (leading and trailing edges, cancel)

Pick native when

Pick native for array, object, and null-safety helpers.

  • structuredClone is Baseline since 2022 and in Node 17+; Object.groupBy and Map.groupBy are Baseline 2024 (Chrome 117, Firefox 119, Safari 17.4, Node 21+).
  • Check your browser and Node targets before using Object.groupBy; polyfill or use a library for older targets.
  • Lint with eslint-plugin-you-dont-need-lodash-underscore to find replaceable calls.

Pick a library when

Pick lodash-es or es-toolkit for the helpers native code does not cover.

  • Deep merge for config objects, and debounce or throttle with cancel and leading-edge options.
  • Cloning values structuredClone rejects or flattens, such as objects holding functions or class instances.
  • A large codebase already built on Lodash: replace calls as files change; do not do a big-bang rewrite.
  • Always use named imports from lodash-es (or lodash/<fn>) so bundlers can drop the rest. Never import _ from "lodash" in browser code.
import { debounce, merge } from "lodash-es";
const search = debounce(runSearch, 250);

Migrate

Replace by call site, widest wins first: whole-library imports, then _.get, _.flatten, _.uniq, and _.cloneDeep on plain data. Keep merge and debounce until you pick a replacement. Remove the dependency when grep finds no imports, and run the bundle analyzer from vite-vs-webpack to confirm the saving.

FAQ

Is Lodash still needed in modern JavaScript?

Only for deep merge, debounce, throttle, and deep clone of values structuredClone rejects. Native methods such as structuredClone, Object.groupBy, arr.at(), and optional chaining cover the rest.

How much does Lodash add to my bundle?

Importing Lodash whole costs about 70 KB minified (about 25 KB gzipped). Use named imports from lodash-es so bundlers drop the rest, and never import _ from "lodash" in browser code.

Should I use es-toolkit instead of Lodash?

es-toolkit is a smaller TypeScript-first library with an es-toolkit/compat layer for Lodash APIs, so it suits new code that needs a few helpers. Lodash 4.18.1 is still maintained, so existing code can migrate call by call.

Can structuredClone replace _.cloneDeep?

For plain data, yes; structuredClone is Baseline since 2022 and in Node 17 and later. It throws on functions and DOM nodes, and class instances lose their prototype.