| name | es-toolkit |
| description | es-toolkit utility library guide for modern JavaScript/TypeScript. Use when:
(1) Writing utility functions (array manipulation, object transforms, string conversion,
math operations, type checks), (2) Migrating from lodash, (3) Needing debounce/throttle/retry,
(4) Working with async primitives (Mutex, Semaphore, delay),
(5) Any code that could use es-toolkit instead of custom implementation.
Triggers on: es-toolkit, lodash, utility function, debounce, throttle, groupBy, pick, omit,
merge, cloneDeep, snakeCase, camelCase, isNil, isEqual, retry, Mutex, Semaphore, attempt.
Do NOT use for: general JavaScript questions unrelated to utilities, or React/framework-specific code.
|
es-toolkit Usage Guide
es-toolkit is a modern JavaScript utility library — 2-3x faster and up to 97% smaller than lodash.
It has 100% test coverage, built-in TypeScript types, and supports Node.js 18+, Deno, Bun, and browsers.
Import Rules
ALWAYS use subpath imports for tree-shaking. NEVER import from the top-level barrel.
import { groupBy } from "es-toolkit/array";
import { debounce } from "es-toolkit/function";
import { pick, omit } from "es-toolkit/object";
import { snakeCase } from "es-toolkit/string";
import { sum } from "es-toolkit/math";
import { isNil } from "es-toolkit/predicate";
import { delay, Mutex, Semaphore } from "es-toolkit/promise";
import { attempt } from "es-toolkit/util";
import { mapKeys } from "es-toolkit/map";
import { keyBy } from "es-toolkit/set";
import { Mutex, Semaphore } from "es-toolkit";
import { get, set, template } from "es-toolkit/compat";
import _ from "es-toolkit";
import { groupBy } from "es-toolkit/dist/array";
Decision Guide
Before writing any utility function, check this hierarchy:
-
Native JS/TS — Use native when it's equally readable and performant
Array.prototype.map/filter/reduce/find/some/every/flat/flatMap
Object.keys/values/entries/assign/fromEntries
structuredClone() for deep cloning (but cloneDeep handles edge cases better)
?. optional chaining instead of get(obj, 'a.b.c')
-
es-toolkit — Use when native is verbose, error-prone, or missing the operation
- Array:
groupBy, sortBy, orderBy, uniq, uniqBy, difference, intersection, union, chunk, zip, shuffle, sample
- Object:
pick, omit, pickBy, omitBy, merge, toMerged, cloneDeep, invert
- String:
camelCase, snakeCase, kebabCase, capitalize, pascalCase, constantCase, deburr, escapeRegExp
- Function:
debounce, throttle, once, memoize, retry, flow, flowRight, noop
- Math:
sum, sumBy, mean, meanBy, round, clamp, inRange, random, randomInt
- Predicate:
isNil, isNotNil, isEqual, isEqualWith, isEmpty, isPlainObject
- Promise:
delay, timeout, Mutex, Semaphore
- Util:
attempt, attemptAsync, invariant
-
es-toolkit/compat — Only for lodash migration or when you need exact lodash behavior
get, set, has, template, iteratee, matches, property
- Prefer native
?. over get() — compat get is slower due to path parsing
Quick Reference — Most Used Functions
Array
import {
groupBy,
sortBy,
uniqBy,
difference,
chunk,
zip,
sample,
countBy,
flatMapDeep,
orderBy,
} from "es-toolkit/array";
groupBy(items, item => item.category);
sortBy(users, [u => u.age, u => u.name]);
orderBy(users, ["age", "name"], ["asc", "desc"]);
uniqBy(items, item => item.id);
difference([1, 2, 3], [2, 3]);
chunk([1, 2, 3, 4, 5], 2);
zip(["a", "b"], [1, 2]);
sample([1, 2, 3]);
countBy([1, 2, 3, 4], n => (n % 2 === 0 ? "even" : "odd"));
Object
import {
pick,
omit,
merge,
toMerged,
cloneDeep,
pickBy,
omitBy,
invert,
clone,
} from "es-toolkit/object";
pick(user, ["name", "email"]);
omit(user, ["password", "secret"]);
merge(target, source);
toMerged(target, source);
cloneDeep(complexObj);
pickBy(obj, (value, key) => value != null);
invert({ a: "1", b: "2" });
Function
import {
debounce,
throttle,
once,
retry,
flow,
memoize,
noop,
identity,
} from "es-toolkit/function";
const search = debounce(query => fetchResults(query), 300);
search.cancel();
search.flush();
const leading = debounce(fn, 300, { edges: ["leading"] });
const onScroll = throttle(handleScroll, 100);
const data = await retry(fetchData, {
retries: 5,
delay: attempt => Math.min(100 * 2 ** attempt, 5000),
shouldRetry: (err, attempt) => err.status >= 500,
signal: controller.signal,
});
const transform = flow(trim, toLowerCase, split(" "), filterEmpty);
const initialize = once(() => expensiveSetup());
Promise & Concurrency
import { delay, timeout, Mutex, Semaphore } from "es-toolkit/promise";
await delay(1000);
const result = await timeout(fetchData(), 5000);
const mutex = new Mutex();
await mutex.acquire();
try {
} finally {
mutex.release();
}
const sem = new Semaphore(3);
await sem.acquire();
try {
} finally {
sem.release();
}
String
import {
camelCase,
snakeCase,
kebabCase,
pascalCase,
capitalize,
constantCase,
deburr,
escapeRegExp,
} from "es-toolkit/string";
camelCase("foo-bar");
snakeCase("fooBar");
kebabCase("FooBar");
pascalCase("foo-bar");
constantCase("fooBar");
capitalize("hello");
deburr("cafe\u0301");
escapeRegExp("a.b*c");
Math
import {
sum,
sumBy,
mean,
meanBy,
round,
clamp,
inRange,
random,
randomInt,
} from "es-toolkit/math";
sum([1, 2, 3]);
sumBy(products, p => p.price * p.quantity);
round(1.2345, 2);
clamp(15, 0, 10);
inRange(5, 1, 10);
randomInt(1, 100);
Predicate (Type Guards)
import { isNil, isNotNil, isEqual, isEmpty, isPlainObject } from "es-toolkit/predicate";
isNil(null);
isNotNil(value);
isEqual({ a: 1 }, { a: 1 });
isEmpty([]);
isPlainObject({});
Util
import { attempt, attemptAsync, invariant } from "es-toolkit/util";
const [error, result] = attempt(() => JSON.parse(input));
const [error, data] = await attemptAsync(async () => {
const res = await fetch("/api/data");
return res.json();
});
invariant(user != null, "User must exist");
Lodash Migration
For complete lodash migration details, see references/lodash-migration.md.
Key points:
es-toolkit/compat provides 100% lodash test compatibility (v1.39.3+)
- Import from
es-toolkit/compat for drop-in replacement
- Prefer native
es-toolkit over es-toolkit/compat for better performance
- NOT supported:
sortedUniq, sortedUniqBy, mixin, noConflict, runInContext, method chaining (Seq)
Full API Catalog
For the complete list of all functions by category, see references/api-catalog.md.