mrkeyoor.com_
Sat 19 Sept 15:53 UTC
npmUtilsupdated 19 Sept 2026

lodash review

Lodash 4.18.1 is a CommonJS collection of helpers for arrays, objects, functions, collections, and value conversion. Its remaining strong cases are operations JavaScript does not express as clearly: debounce and throttle controls, deep path access, iteratee shorthands, stable grouping, deep cloning or equality, and the data-last lodash/fp build. Version 4.18.1 repairs ReferenceErrors in modular template and fromPairs builds caused by stale internal build mappings. The project is entering OpenJS Feature-Complete status, which points toward maintenance and compatibility instead of a version 5 redesign.

151.9Mdownloads / wk
Verdict

Lodash 4.18.1 installed in 0.6 seconds with 0 dependencies, but our root browser import cost 25.8 KB gzipped and shipped no TypeScript declarations. Keep it for deep-value, timing, equality, or FP helpers that remove real code; skip the root package for ordinary modern array operations.

We installed it

Lab card: what happened when we installed lodashScreenshot of lodash documentation
Install✓ · 0.6s1 package on disk · 5 MB
ImportESM import works · require() works · CommonJS package
Browser25.8 KBgzipped (72 KB minified), bundled with esbuild
Typesno TypeScript types found
Known vulns00 critical · 0 high · 0 moderate · 0 low (npm audit)

Answers from our run

Does lodash install cleanly?

Yes. In a fresh container with an empty cache, npm install lodash finished in 0.6s, leaving 1 package and 5 MB on disk. npm audit reported no known vulnerabilities.

How much does lodash add to a browser bundle?

25.8 KB gzipped (72 KB minified) when the whole package is bundled for the browser with esbuild. Importing only part of it is usually smaller.

Does lodash work with both ESM and CommonJS?

Yes. Both import 'lodash' and require('lodash') worked in Node 22 in our run. The package is published as CommonJS.

Does lodash include TypeScript types?

No type declarations were found in our install, so TypeScript users need their own declarations.

lodash or radash: which should you use?

radash: Use it for a modern TypeScript utility set that also includes async helpers. Lodash 4.18.1 installed in 0.6 seconds with 0 dependencies, but our root browser import cost 25.8 KB gzipped and shipped no TypeScript declarations.

When should you not use lodash?

The feature only needs map, filter, find, Object.entries, optional chaining, or structuredClone; current JavaScript already supplies them

API stability5/5Lodash 4.18.1 keeps the 4.x method names, chaining, iteratee shorthands, modular paths, and lodash/fp conventions used for years. The release repairs generated module dependencies without changing normal calls. OpenJS Feature-Complete status makes preservation an explicit direction, although CommonJS, the separate ESM distribution, and multiple build flavors are also likely to remain part of that fixed shape.
Docs4/5The 4.18.1 documentation gives signatures, arguments, return values, introduction versions, mutation notes, and examples for the complete method catalog. The repository links separate FP and build-difference guides. Looking up a known function is quick. Deciding between the root UMD build, core, method paths, lodash-es, and lodash/fp takes more work, and the README still includes commands and module advice shaped by older bundlers.
Maintenance4/5GitHub shows an unarchived repository pushed July 3, 2026, with 106 open issues and pull requests, while npm published 4.18.1 on April 1, 2026. That release fixed real failures in generated template and fromPairs modules. Sovereign Tech Agency support and renewed OpenJS governance provide named stewardship, though Feature-Complete status means consumers should expect security and compatibility fixes more often than new methods.
Ecosystem5/5npm recorded 175,418,823 downloads from August 19 through 25, 2026, and GitHub lists 61,283 stars. The package has 0 runtime dependencies, works through require(), and loaded via Node ESM interop in our test. Separate type declarations, lodash-es, lodash/fp, method entries, build plugins, and years of framework examples create broad compatibility, at the cost of several competing import conventions.

Discussed on

  1. hnLodash 4.0.0 is out303 points
  2. hnGoogle Took Down My Chrome Extension for Using Lodash286 points
  3. hnLodash v3.0.0245 points
  4. hnLodash just declared issue bankruptcy and closed every issue and open PR240 points
  5. hnUnderscore and Lodash Merge Thread208 points

Use it if

  • An established codebase uses Lodash shorthands heavily and removal would add churn without shrinking shipped output
  • You need documented debounce, throttle, memoize, cloneDeep, isEqual, or nested-path behavior
  • A Node service wants one dependency-free compatibility layer across several runtime generations
  • The project deliberately uses lodash/fp for curried, immutable, data-last composition
Skip it if

Setup reality

We installed Lodash 4.18.1 in a fresh Node 22 sandbox in 0.6 seconds. It produced 1 package and 5 MB on disk, and npm audit found 0 known vulnerabilities. Lodash declares 0 direct dependencies and 0 peer dependencies. The package itself is 5,008 KB unpacked. It is CommonJS without an exports map; require() and ESM import both worked. No TypeScript declarations were present.

Our full esbuild browser import measured 72 KB minified and 25.8 KB gzipped. Lodash needs no credentials or config file, so import shape is the main setup choice. The root path loads the full build. Paths such as lodash/debounce can narrow an entry, and lodash-es is a separate ESM package. lodash/fp also changes argument order, curries methods, and avoids mutation. Mixing FP and ordinary examples produces convincing but incorrect calls.

memoize keeps entries until code deletes or clears them, and its default cache key is only the first argument. debounce and throttle retain timers and the latest arguments until invocation or cancel(). Long-lived workers and disposed UI components should call cancel. flush forces pending work immediately, which is useful only when the caller genuinely wants delivery during cleanup.

Deep paths accept strings such as a[0].b or arrays of keys. A caller-supplied path is still untrusted input and should not become permission to traverse arbitrary fields. cloneDeep handles many data values, yet sockets, DOM nodes, class instances, and application resources may need an explicit copier. Version 4.18.1 fixes generated modular artifacts for template and fromPairs; it does not alter their public signatures.

Patterns

Group records by one derived value group-records

import groupBy from 'lodash/groupBy.js';
const byStatus = groupBy(orders, order => order.status);

groupBy returns an object and stringifies keys; choose Map when object identity must survive.

Read a deep field with a fallback read-nested-value

import get from 'lodash/get.js';
const city = get(profile, ['address','city'], 'unknown');

The fallback applies to undefined, while an explicit null value is returned unchanged.

Write through a checked key path set-nested-value

import set from 'lodash/set.js';
set(settings, ['editor','tabSize'], 2);

set mutates its first argument, and untrusted paths should be rejected before this call.

Keep the first record for each key dedupe-by-key

import uniqBy from 'lodash/uniqBy.js';
const unique = uniqBy(users, user => user.id);

uniqBy preserves input order and discards later records whose derived key has appeared.

Delay repeated search calls debounce-search

import debounce from 'lodash/debounce.js';
const searchLater = debounce(runSearch, 250, { maxWait: 1000 });
searchLater(query);

The returned function retains a timer and arguments; call cancel when its owner is disposed.

Cap progress update frequency throttle-progress

import throttle from 'lodash/throttle.js';
const report = throttle(sendProgress, 200, { leading: true, trailing: true });

A trailing invocation holds the newest arguments until it runs or report.cancel removes it.

Cache using both arguments memoize-compound-key

import memoize from 'lodash/memoize.js';
const loadUser = memoize(fetchUser, (tenantId, userId) => tenantId + ':' + userId);

Without a resolver, memoize keys only on the first argument and also retains rejected promises.

Compose data-last FP helpers compose-fp-pipeline

import flow from 'lodash/fp/flow.js';
import map from 'lodash/fp/map.js';
import filter from 'lodash/fp/filter.js';
const names = flow(filter(u => u.active), map(u => u.name));

lodash/fp uses iteratee-first, data-last arguments and caps iteratee arity, unlike ordinary Lodash.

Alternatives

PackageRegistryPick it when
radashnpmUse it for a modern TypeScript utility set that also includes async helpers
remedanpmUse it for strong inference across data-first and data-last pipelines
underscorenpmUse it only when an older application already depends on Underscore semantics

More utils guides

lru-cache · type-fest · ajv · p-limit · find-up · js-yaml · the whole shelf →

How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.