ES-Toolkit

1.45.1 · active · verified Sun Apr 19

ES-Toolkit is a modern, high-performance JavaScript utility library designed for both Node.js and browser environments, emphasizing a small bundle size and robust TypeScript type annotations. Currently at version 1.45.1, the library demonstrates an aggressive release cadence, with updates typically arriving monthly or bi-monthly, reflecting continuous development and refinement. Key differentiators include its focus on performance, minimal footprint, and comprehensive type definitions which make it an excellent choice for TypeScript projects. It offers a wide array of functions for array manipulation, object operations, asynchronous utilities, and more, often providing Lodash-like functionality with a modern, tree-shakable architecture. Recent updates have focused on refining type safety, enhancing compatibility with Lodash behaviors, and introducing async utility methods.

Common errors

Warnings

Install

Imports

Quickstart

Demonstrates core utility functions like deep cloning, object emptiness checks, throttling, asynchronous mapping, and retrying operations, highlighting its modern API and TypeScript compatibility.

import {
  cloneDeep,
  isEmptyObject,
  throttle,
  mapAsync,
  retry,
} from 'es-toolkit';

interface User {
  id: number;
  name: string;
  data?: Record<string, any>;
}

const users: User[] = [
  { id: 1, name: 'Alice', data: { age: 30 } },
  { id: 2, name: 'Bob', data: {} },
  { id: 3, name: 'Charlie' },
];

// Example 1: Deep cloning objects
const clonedUsers = cloneDeep(users);
console.log('Cloned Users:', clonedUsers);
console.log('Are they the same object reference?', clonedUsers === users); // false

// Example 2: Checking for empty objects
const userWithEmptyData = users[1];
console.log(`User ${userWithEmptyData.name} has empty data:`, isEmptyObject(userWithEmptyData.data));

// Example 3: Throttling a function
let count = 0;
const throttledIncrement = throttle(() => {
  count++;
  console.log('Throttled increment called, count:', count);
}, 100);

throttledIncrement();
setTimeout(throttledIncrement, 50); // Will not trigger
setTimeout(throttledIncrement, 150); // Will trigger again

// Example 4: Asynchronous mapping
const fetchUserData = async (id: number) => {
  await new Promise(resolve => setTimeout(resolve, 50 * id)); // Simulate async
  return { id, status: 'fetched' };
};

(async () => {
  const userStatuses = await mapAsync(users, async (user) => {
    return fetchUserData(user.id);
  });
  console.log('User statuses:', userStatuses);
})();

// Example 5: Retrying a failing operation
let attempt = 0;
const flakyOperation = async () => {
  attempt++;
  if (attempt < 3) {
    console.log(`Flaky operation attempt ${attempt}: Failing...`);
    throw new Error('Transient error');
  }
  console.log(`Flaky operation attempt ${attempt}: Succeeded!`);
  return 'Success';
};

(async () => {
  try {
    const result = await retry(flakyOperation, { retries: 5, delay: 100 });
    console.log('Retry result:', result);
  } catch (e) {
    console.error('Retry failed:', (e as Error).message);
  }
})();

view raw JSON →