Skip to main content

es-toolkit

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.

معلومات المصدر

المستودع
pedronauck/devstack
آخر نشاط في المصدر
١٥ مارس ٢٠٢٦ في ٢٠:١١
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
٩
التفرعات
٠

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

مستكشف الملفات
3 ملفات

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
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. ```typescript // CORRECT — subpath imports (tree-shakeable) 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"; // ALSO CORRECT — top-level for classes/quick scripts import { Mutex, Semaphore } from "es-toolkit"; // CORRECT — compat layer (lodash-compatible API) import { get, set, template } from "es-toolkit/compat"; // WRONG — never do this import _ from "es-toolkit"; import { groupBy } from "es-toolkit/dist/array"; ``` ## Decision Guide Before writing any utility function, check this hierarchy: 1. **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')` 2. **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` 3. **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 ```typescript import { groupBy, sortBy, uniqBy, difference, chunk, zip, sample, countBy, flatMapDeep, orderBy, } from "es-toolkit/array"; groupBy(items, item => item.category); // Record<string, T[]> sortBy(users, [u => u.age, u => u.name]); // T[] — stable multi-key sort orderBy(users, ["age", "name"], ["asc", "desc"]); // T[] — with direction control uniqBy(items, item => item.id); // T[] — unique by key difference([1, 2, 3], [2, 3]); // [1] chunk([1, 2, 3, 4, 5], 2); // [[1,2], [3,4], [5]] zip(["a", "b"], [1, 2]); // [["a",1], ["b",2]] sample([1, 2, 3]); // random element countBy([1, 2, 3, 4], n => (n % 2 === 0 ? "even" : "odd")); // { even: 2, odd: 2 } ``` ### Object ```typescript import { pick, omit, merge, toMerged, cloneDeep, pickBy, omitBy, invert, clone, } from "es-toolkit/object"; pick(user, ["name", "email"]); // { name, email } omit(user, ["password", "secret"]); // everything except those keys merge(target, source); // deep merge (MUTATES target) toMerged(target, source); // deep merge (returns NEW object) cloneDeep(complexObj); // deep clone (handles Date, RegExp, Map, Set) pickBy(obj, (value, key) => value != null); // pick by predicate invert({ a: "1", b: "2" }); // { "1": "a", "2": "b" } ``` ### Function ```typescript import { debounce, throttle, once, retry, flow, memoize, noop, identity, } from "es-toolkit/function"; // Debounce with cancel/flush and AbortSignal support const search = debounce(query => fetchResults(query), 300); search.cancel(); search.flush(); // Debounce with leading edge const leading = debounce(fn, 300, { edges: ["leading"] }); // Throttle const onScroll = throttle(handleScroll, 100); // Retry with exponential backoff const data = await retry(fetchData, { retries: 5, delay: attempt => Math.min(100 * 2 ** attempt, 5000), shouldRetry: (err, attempt) => err.status >= 500, signal: controller.signal, }); // Function composition pipeline const transform = flow(trim, toLowerCase, split(" "), filterEmpty); // Execute only once const initialize = once(() => expensiveSetup()); ``` ### Promise & Concurrency ```typescript import { delay, timeout, Mutex, Semaphore } from "es-toolkit/promise"; await delay(1000); // wait 1 second const result = await timeout(fetchData(), 5000); // timeout after 5s // Mutex — single concurrent task const mutex = new Mutex(); await mutex.acquire(); try { /* critical section */ } finally { mutex.release(); } // Semaphore — N concurrent tasks const sem = new Semaphore(3); await sem.acquire(); try { /* max 3 concurrent */ } finally { sem.release(); } ``` ### String ```typescript import { camelCase, snakeCase, kebabCase, pascalCase, capitalize, constantCase, deburr, escapeRegExp, } from "es-toolkit/string"; camelCase("foo-bar"); // "fooBar" snakeCase("fooBar"); // "foo_bar" kebabCase("FooBar"); // "foo-bar" pascalCase("foo-bar"); // "FooBar" constantCase("fooBar"); // "FOO_BAR" capitalize("hello"); // "Hello" deburr("cafe\u0301"); // "cafe" escapeRegExp("a.b*c"); // "a\\.b\\*c" ``` ### Math ```typescript import { sum, sumBy, mean, meanBy, round, clamp, inRange, random, randomInt, } from "es-toolkit/math"; sum([1, 2, 3]); // 6 sumBy(products, p => p.price * p.quantity); // total round(1.2345, 2); // 1.23 clamp(15, 0, 10); // 10 inRange(5, 1, 10); // true randomInt(1, 100); // random integer in [1, 100) ``` ### Predicate (Type Guards) ```typescript import { isNil, isNotNil, isEqual, isEmpty, isPlainObject } from "es-toolkit/predicate"; isNil(null); // true — null or undefined isNotNil(value); // true — narrows type to exclude null/undefined isEqual({ a: 1 }, { a: 1 }); // true — deep structural equality isEmpty([]); // true isPlainObject({}); // true ``` ### Util ```typescript import { attempt, attemptAsync, invariant } from "es-toolkit/util"; // Safe sync execution — returns [error, result] tuple const [error, result] = attempt(() => JSON.parse(input)); // Safe async execution const [error, data] = await attemptAsync(async () => { const res = await fetch("/api/data"); return res.json(); }); // Invariant — throws if condition is falsy invariant(user != null, "User must exist"); ``` ## Lodash Migration For complete lodash migration details, see [references/lodash-migration.md](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](references/api-catalog.md).
عرض على GitHub