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
| Task | Native | When a library still wins |
|---|---|---|
| Deep clone | structuredClone(obj) | Values holding functions or DOM nodes (structuredClone throws); class instances lose their prototype |
| Flatten, last, find | arr.flat(), arr.at(-1), arr.find() | None |
| Safe access | a?.b?.c ?? fallback | Dynamic string paths (_.get(obj, path)) |
| Group by | Object.groupBy(arr, fn), Map.groupBy | Older runtimes |
| Unique | [...new Set(arr)] | _.uniqBy on keys |
| Deep merge | None (spread is shallow) | _.merge, es-toolkit merge |
| Debounce, throttle | None | _.debounce, _.throttle (leading and trailing edges, cancel) |
Pick native when
Pick native for array, object, and null-safety helpers.
structuredCloneis Baseline since 2022 and in Node 17+;Object.groupByandMap.groupByare 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-underscoreto 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
debounceorthrottlewith cancel and leading-edge options. - Cloning values
structuredClonerejects 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(orlodash/<fn>) so bundlers can drop the rest. Neverimport _ 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.