Written by Rishi Purwar✏️
If you’ve been building JavaScript applications for a while, you’ve probably used utility libraries like Lodash. These libraries are packed with useful functions that make coding in JavaScript easier and more efficient. But as your project grows and you start using more utility functions, you might notice that your bundle size also starts increasing.
This is especially true when you rely on heavy libraries like Lodash, which makes you wonder if there is a better alternative.
That’s where es-toolkit comes in — a modern, high-performance JavaScript utility library that’s lightweight and comes with solid TypeScript support, making it a great alternative to popular libraries like Lodash.
These are the main comparisons between es-toolkit and Lodash:
- es-toolkit offers key utility functions similar to Lodash, covering areas like functions, arrays, objects, strings, math, predicates, and promises
- es-toolkit’s functions are often faster than Lodash’s because they use modern JavaScript APIs in their implementations and TypeScript for type checking, reducing the need for extra defensive code.
- Performance benchmarks show that es-toolkit functions outperform Lodash equivalents, sometimes by significant margins
- es-toolkit’s functions have significantly smaller bundle sizes compared to Lodash’s equivalents, leading to faster load times and better performance
- es-toolkit addresses performance and bundle size challenges by leveraging modern JavaScript features and avoiding the interdependencies found in Lodash
- es-toolkit functions are mostly standalone, preventing unintended inclusion of unnecessary code, unlike Lodash where utility functions are often interdependent
Let’s get into the nitty-gritty about these differences and see how you can use es-toolkit in your JavaScript projects.
Key features of es-toolkit
Here’s a quick look at what es-toolkit brings to the table:
- Functions including
memoize
to cache function results anddebounce
to limit how often a function is called - Arrays like
uniq
to filter out duplicates anddifference
to find what’s different between arrays - Tools for handling JavaScript objects, such as
cloneDeep
for deep cloning andflattenObject
to transform nested objects into a flat structure - String manipulation tools, including
kebabCase
to convert strings to kebab-case - Math helpers like
random
for generating random numbers andround
for rounding them off - Type guard functions like
isNil
to easily check fornull
orundefined
values - Utilities for working with asynchronous code, like
delay
to pause execution for a bit
Performance and bundle size comparison
To truly understand the benefits of es-toolkit, let's compare its performance and bundle size to Lodash.
Performance
es-toolkit’s functions are often faster than Lodash’s because they use modern JavaScript APIs in their implementations. For example, es-toolkit’s omit
function is about 11.8 times faster than lodash’s omit
function.
Here’s a table comparing the performance of es-toolkit
and lodash-es
for various functions:
Function | es-toolkit@0.0.1 | lodash-es@4.17.21 | Difference |
---|---|---|---|
omit | 4,767,360 times | 403,624 times | 11.8× |
pick | 9,121,839 times | 2,663,072 times | 3.43× |
differenceWith | 9,291,897 times | 4,275,222 times | 2.17× |
difference | 10,436,101 times | 5,155,631 times | 2.02× |
intersectionWith | 8,074,722 times | 3,814,479 times | 2.12× |
intersection | 9,999,571 times | 4,630,316 times | 2.15× |
unionBy | 6,435,983 times | 3,794,899 times | 1.69× |
union | 5,059,209 times | 4,771,400 times | 1.06× |
dropRightWhile | 7,529,559 times | 5,606,439 times | 1.34× |
groupBy | 5,000,235 times | 5,206,286 times | 0.96× |
Bundle size
When it comes to bundle size, es-toolkit really shines. A smaller bundle size means your web applications will load faster and perform better, especially on slower networks.
Here’s a comparison of the bundle sizes for some common functions in es-toolkit
and lodash-es
:
Function | es-toolkit@0.0.1 | lodash-es@4.17.21 | Difference |
---|---|---|---|
sample | 88 bytes | 2,000 bytes | -95.6 percent |
difference | 91 bytes | 3,190 bytes | -97.2 percent |
sum | 152 bytes | 413 bytes | -63.2 percent |
debounce | 144 bytes | 1,400 bytes | -89.7 percent |
throttle | 110 bytes | 1,460 bytes | -92.5 percent |
pick | 657 bytes | 3,860 bytes | -83.0 percent |
zip | 797 bytes | 1,790 bytes | -55.5 percent |
es-toolkit’s functions are much smaller compared to their Lodash counterparts. For instance, the sample
function in es-toolkit is only 88 bytes, whereas the same function in Lodash is 2,000 bytes — nearly 96 percent smaller!
Using es-toolkit in a JavaScript app
Let’s look into some examples to see how easy it is to use es-toolkit in a JavaScript application. In this section, we’ll explore how es-toolkit handles common tasks like debouncing, throttling, picking specific properties from objects, and removing duplicates from an array.
And guess what? To make things even easier, I’ve put together a starter code repository on GitHub that you can clone and start experimenting with right away. You’ll find the HTML and CSS code for all the examples we will cover, along with everything you need to get started. Check out the repo here and follow along.
Debounce example
Let’s say you’re building a search feature for a website where users can look up information on different topics.
You want to fetch data as the user types but without sending a request for every single keystroke; otherwise, you might flood the API with too many calls. That’s where the debounce function from es-toolkit comes in handy.
Here’s how it works:
import { debounce } from "es-toolkit";
// a function that simulates an API call
function fetchData(query) {
console.log(`Fetching data for: ${query}`);
}
// Using es-toolkit debounce function
const debouncedFetchData = debounce(fetchData, 1000);
document.getElementById("search-input").addEventListener("input", (event) => {
const query = event.target.value;
debouncedSearch(query);
});
In the below demo, even though I typed out five letters, the fetchData
function only gets called after I’ve stopped typing for a second.
This way, we can avoid making unnecessary API requests on every keypress using the debounce function.
Throttle example
Suppose you have a button on your webpage that loads more posts when clicked. To prevent multiple API calls if the button is clicked too quickly, you can use the throttle function from es-toolkit. It ensures the API call happens only at set intervals, even if the button is clicked several times.
Here’s how you can use it:
// Throttle Example
import { throttle } from "es-toolkit";
// Function to fetch posts from an API
async function fetchPosts() {
console.log("Fetching new posts...");
const response = await fetch("https://jsonplaceholder.typicode.com/posts");
const posts = await response.json();
console.log("Posts fetched:", posts);
}
// Create a throttled version of fetchPosts
const throttledFetchPosts = throttle(fetchPosts, 2000);
// Set up an event listener on the button
document.getElementById("fetch-more-posts").addEventListener("click", () => {
console.log("button clicked");
throttledFetchPosts();
});
In this example, even if a user clicks the “Fetch More Posts” button rapidly, the fetchPosts
function will only be triggered once every two seconds, as shown in the demo below.
Pick example
Let’s say you have detailed user profile data, but you only want to display specific properties like username, email, and age in the user summary component. The pick
function helps you extract these properties easily.
Here’s a demonstration of how it works:
// Pick Example
import { pick } from "es-toolkit";
// dummy user data
const user = {
id: 1,
username: "johndoe",
firstName: "John",
lastName: "Doe",
email: "john.doe@example.com",
age: 30,
address: {
street: "123 Main St",
city: "Anytown",
country: "USA",
},
phoneNumber: "1234-5678",
};
// Use pick to select specific properties
const pickedUser = pick(user, ["username", "email", "age"]);
console.log("pickedUser", pickedUser)
In this example, the pick
function extracts the username
, email
, and age
properties from the user
object. The console log will output:
pickedUser: { username: 'johndoe', email: 'john.doe@example.com', age: 30 }
Uniq example
Imagine you’re running a blog where users can add tags to categorize their posts. You want to make sure that each tag only appears once. This is where the uniq
function from es-toolkit is super useful. It helps you filter out duplicates from an array and get a list of unique tags.
Here’s a practical example:
>import { uniq } from "es-toolkit";
// Array of tags with some duplicates
const tags = [
"javascript",
"coding",
"webdev",
"programming",
"javascript",
"react",
"nodejs",
"coding",
"html",
"css",
"webdev",
"frontend",
];
// Use uniq to filter out duplicate tags
const uniqueTags = uniq(tags);
console.log("uniqueTags", uniqueTags);
In the above example, the uniq
function removes duplicates from the tags
array. The console log will output:
uniqueTags: ['javascript', 'coding', 'webdev', 'programming', 'react', 'nodejs', 'html', 'css', 'frontend']
How es-toolkit addresses performance and bundle size challenges
You might be curious about how es-toolkit tackles these challenges. Under the hood, es-toolkit leverages modern JavaScript APIs to deliver faster performance and significantly smaller bundle sizes.
On top of that, es-toolkit uses TypeScript, which helps cut out a lot of the extra defensive code that usually checks argument types at runtime. This not only makes the code run more efficiently but also minimizes any unnecessary overhead that can slow things down.
Another key difference is that Lodash utility functions are often interdependent, meaning that importing one function can drag in many others along with it. In contrast, es-toolkit functions are mostly standalone, which helps keep your bundle lightweight.
To really see the difference, you can use webpack-bundle-analyzer
to visualize the size of your bundle. I've set everything up for you, so all you need to do is checkout to main
branch and run npm i && npm run build
from the root of the cloned repository, and it will open a page with all the details about your bundle.
The image below shows the bundle size when using es-toolkit
. You can see that most es-toolkit functions are standalone, which results in smaller bundle sizes.
Now, let's replace es-toolkit
with lodash-es
in the import statements from the examples above and run npm run build
again to check the lodash-es
bundle size.
The image below shows that Lodash functions are mostly interdependent, pulling in many other utilities when importing just one:
Conclusion
es-toolkit can be a great alternative to utility libraries like Lodash, especially when performance and bundle size are key considerations. Its small bundle size, modern JavaScript features usage, and solid TypeScript support make it an excellent choice for developers.
I hope you found this exploration of es-toolkit helpful for your JavaScript projects, but don’t stop here! I encourage you to try out es-toolkit in your own applications and share your experiences with us in the comments below. Happy coding!
Are you adding new JS libraries to improve performance or build new features? What if they’re doing the opposite?
There’s no doubt that frontends are getting more complex. As you add new JavaScript libraries and other dependencies to your app, you’ll need more visibility to ensure your users don’t run into unknown issues.
LogRocket is a frontend application monitoring solution that lets you replay JavaScript errors as if they happened in your own browser so you can react to bugs more effectively.
LogRocket works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app’s performance, reporting metrics like client CPU load, client memory usage, and more.
Build confidently — Start monitoring for free.
Top comments (0)