Of Mice and Toolkits

Issue #412.July 28, 2025.2 Minute read.
Bytes

Today’s issue: Killing SPAs, getting radicalized by Airbnb’s lint rules, and learning valuable JavaScript lessons from my iPod Nano.

Welcome to #412.


Eyeballs logo

The Main Thing

The bee from the Bee movie disintegrating like in Avengers

I'll never forget you, Lodash

Of Mice and Toolkits

One year ago we highlighted a new project called es-toolkit, which bills itself as a “state-of-the-art, high-performance JavaScript utility library” that’s 2-3x faster and 97% smaller than Lodash.

And it was back in the news again last week thanks to its new Lodash compatibility layer, which makes it easier than ever to migrate away from dear old Lodie.

But you might be thinking, do we really still need utility libraries in the Year of our Spec, 2025?

It’s a fair question considering how far JavaScript has come – but in the past year, es-toolkit has grown to 3 million weekly npm downloads and is now being used in major projects like Storybook, Ink, and Recharts.

Let’s take a look at why:

  • Built for modern JavaScript – It doesn’t reimplement existing JS features like map and filter. Instead, it fills in actual language gaps with focused helpers like debounce, delay, sum, and pick.

  • Solid TypeScript support – All functions come with clear, predictable types that play nicely with type inference. You also get useful type guards like isNotNil without needing to be an expert in conditionals.

  • Optimized for modern toolchains – Fully tree-shakeable, and tiny by default. Works out of the box with modern environments like Deno and Bun, and leverages modern JavaScript APIs for easy implementation.

Bottom Line: We don’t need utility libs as much as we did back in Lodash’s golden age of the late 2010s. But when one comes along that’s fast, type-safe, and actually helpful, we’re not gonna say no – especially if it can easily shave off some Old Lodie bloat in the process.


CodeRabbit logo

Our Friends
(With Benefits)

Painting of Saint Francis holding some doves

Tfw you can use AI to catch all the AI slop code

Get AI code reviews in your IDE – for free

CodeRabbit just launched a new VS Code extension that gives you line-by-line code reviews right in your editor.

And it understands the full context of your entire codebase, allowing it to catch complex bugs and subtle issues before you even submit a PR.

It’s great for:

  • Catching AI slop – so you can actually trust the code that Copilot generates for you, without manually reviewing it all yourself

  • One-click fixes – instantly incorporate the changes back into your codebase

  • Fixing with AI – hand off CodeRabbit’s recommended changes and deep context back to your code agent, so it can make the changes for you

Install the free VS Code extension – and see what it’s like having a senior developer check every line of your code (without judging you).


Spot the Bug logo

Spot the Bug

Sponsored by Postman

They created this free 90-day AI Readiness Playbook to show engineering leaders exactly how to transform APIs into AI-ready tools that agents can discover and execute reliably.

function* userGenerator(users) {
  for (let user of users) {
    if (!user.isActive) {
      return;
    }
    yield user;
  }
}

const users = [
  { name: "Ben", isActive: true },
  { name: "Alex", isActive: false },
  { name: "Tyler", isActive: true },
];

const gen = userGenerator(users);

for (let user of gen) {
  console.log(user);
}

Cool Bits logo

Cool Bits

  1. Jamie wrote a very well-researched article about the many, many, many JavaScript runtimes of the last decade.

  2. Devon Govett wrote an interesting, technical deep-dive about how Parcel bundles React Server Components.

  3. The Augment Code team just launched Tasklist – a transparent workflow for your coding agent that stores each step of your prompt as a first-class object with typed metadata. That means programmatic access and real-time updates for your tasks, while your agent plans and executes them. [sponsored]

  4. eslint-config-prettier and several other linter packages were hijacked last week in a supply chain attack by some rogue developers who were most likely radicalized by Airbnb’s ESLint rules.

  5. Jono Alderson wrote about how it’s time for modern CSS to kill the SPA. A little aggressive, but we love a strong hook.

  6. The Sentry team wrote this in-depth guide on what you actually need to monitor AI systems in production – so you can do your part to prevent The Great Sloppening of the internet. [sponsored]

  7. Dan Webb wrote about how he and his team migrated their site from Next.js to Eleventy and improved performance by 24%. But who knows, maybe he’s just deep in Big Static’s pocket.

  8. TkDodo wrote about The useless useCallback.

  9. Daniel Ehrenberg wrote an article asking, when is WebAssembly going to get DOM support? But every time we ask, they add 6 months to the counter.

  10. Mux (the video API for developers that we use for all our courses) just announced their biggest price drop ever, thanks to some infrastructure improvements and optimizations that cut Mux Video prices by over 20%. You can read about how they did it here. [sponsored]

  11. Ibrahim Diallo wrote about revisiting his 2010 JavaScript library, which he calls “a true relic from the past and a testament to just how far we’ve come.” I felt the same way when I found my old iPod Nano and saw that it was mostly just a bunch of Weird Al Yankovic songs pirated from LimeWire.

  12. In other nostalgia-related news, MDN just turned 20 years old and is now legally old enough to do a bunch of whippets in a frat house basement.


Spot the Bug logo

Spot the Bug: Solution

Sponsored by Postman

return will stop the generator, so the second user will not be yielded which causes only the user object for Ben to be logged (instead of both Ben and Tyler). To fix this, use continue instead of return.

function* userGenerator(users) {
  for (let user of users) {
    if (!user.isActive) {
      continue;
    }
    yield user;
  }
}

const users = [
  { name: "Ben", isActive: true },
  { name: "Alex", isActive: false },
  { name: "Tyler", isActive: true },
];

const gen = userGenerator(users);

for (let user of gen) {
  console.log(user);
}