
Today’s issue: Using Sora to develop good taste, firing up the OpenClaw Kernel Module, and coping with the side effects of AI’s Rust expertise.
Welcome to #465.


When AI boosts your downloads by 5x, but kills all your revenue
No, I don’t have any insider knowledge, but last week’s Tailwind CSS v4.2 release has me convinced that a Tail-cel marriage is coming sooner or later.
But first, let’s back up to how we got here.
When the Tailwind team launched Tailwind UI back in Feb 2020, they made $400k on day one. Over the next few years, they built one of the most successful bootstrapped OSS businesses of all time, raking in millions of dollars of high-margin revenue that let them fund a small team, organize conferences, and invest a lot of resources in the core library.
And if you fix CSS for basically the entire internet, you deserve to get rich.
But last month, Adam Wathan shared that Tailwind revenue had been shrinking significantly for the past couple years, forcing them to lay off 75% of their small engineering team to stay afloat.
What caused this? AI. But not in the way you might think.
LLMs massively increased Tailwind adoption, with weekly npm installs up 5x in the past two years. But LLMs also led to a 40% decrease in human visits to the Tailwind docs, which is the only place they promote their paid products. The singularity giveth and it taketh away.
Now let’s fast forward to last week’s Tailwind v4.2 release. The headline feature is a new @tailwindcss/webpack package that lets you run Tailwind as a webpack plugin, producing a “huge performance boost” in frameworks like Next.js. Adam also mentioned that many new v4.2 features were built in direct collaboration with Netflix and Vercel as part of Tailwind’s paid Partners Program.
And that’s when my That’s So Raven senses started tingling.
Tailwind needs a more stable funding model than fickle corporate sponsors (who can only be guilted so often), and docs traffic that definitely won’t stop declining anytime soon. Adam has also hinted that they’re open to an acquisition.
Vercel has a mountain of cash, a vested interest in Tailwind’s success, and a good track record of acquiring and stewarding projects like Svelte, shadcn/ui, and Turborepo. Plus, they’d get the Tailwind team, at least until Adam leaves to go work on William Shatner’s new heavy metal album full time.
Bottom Line: No business has a right to exist forever (RIP TGI Fridays). But Tailwind-the-framework is looking increasingly Too Big To Fail™️, so don’t be surprised if we see a triangle-shaped bailout in the future.


Me after daring myself to look at our team’s CI bill
E2E testing has always been expensive, and mobile makes it even worse.
But the harder question is, do you actually know what each mobile QA cycle costs?
Most teams don’t. That’s why QA Wolf’s Senior Engineering Director, Eric Eidelberg is hosting this free workshop covering:

The MCP Workbench is an open-source visual debugger that lets you see *exactly* where your MCP server is going wrong, at the protocol level. This article shows how it works.
How would you remove the duplicate elements from this array?
const list = [
{ name: 'John' },
{ name: 'Sara' },
{ name: 'Sara' },
{ name: 'Lynn' },
{ name: 'Jake' }
];

Emil Kowalski shared some thoughts on how to develop taste as a software developer. My approach has been to mindlessly scroll Sora for hours before bed every night and to only take advice from Patagonia vest-wearing VCs.
Expo’s Claude Skills automatically apply Expo’s best practices for routing, data fetching, and deployment inside Claude Code. “Build me a cross-platform mobile app with Expo and make no mistakes” is actually becoming a real thing now. [sponsored]
Ko-Hsin Liang did a static analysis of 500 high-profile public repos and found that 86% of them have at least one missing-cleanup pattern with potential frontend memory leak instances.
Andreas Kling wrote about how he ported Ladybird’s JavaScript engine to Rust using AI. It only took him two weeks of human-directed work, but it also left him with a lingering desire to watch niche anime and attend his local furry meetup.
Clerk just expanded its free tier to 50,000 MRUs. And you get MFA, device tracking, and satellite domains included in Pro at $20/mo, with automatic volume discounts as you scale. If you’ve been duct-taping auth together, this is the math that makes it stop making sense. [sponsored]
Drew Breunig wondered why Claude is an Electron app, if all code is free?
Claude Code just turned 1 year old, and Anthropic celebrated by accusing other companies of training their AI models on Anthropic’s proprietary dataset, including the millions of books, movies, music, and lines of code that they’ve spent the last 200 years painstakingly creating from scratch.
Harvey just released BigLaw Bench: Arena to show how AI models stack up at legal tasks according to lawyers. Looks like Harvey Assistant will be tough to beat. [sponsored]
Adolfo Ochagavía wrote a quick post about fixing your tools, after a stubborn bug in his code was completely missed by a buggy debugger.
The OKLCH color model is designed to help you create perceptually uniform color palettes, consistent with how humans actually see them. But I personally haven’t been able to perceive the color red since the solar eclipse in ‘99, so good luck.
Emil Kowalski shared their experience of building a toast library called Sonner.
NanoClaw is a lightweight alternative to OpenClaw that runs agents securely in their own containers. But I personally prefer the OpenClaw Kernel Module that lets me unlock the full power of the Agentic Kernel without being burdened by your petty “security” concerns.
How would you remove the duplicate elements from this array?
const list = [
{ name: 'John' },
{ name: 'Sara' },
{ name: 'Sara' },
{ name: 'Lynn' },
{ name: 'Jake' }
];
There are a few ways to do this. Your first intuition might be to do something like this.
const uniqueList = Array.from(new Set(list))
It’s the right idea since creating a Set will ensure our collection only contains unique values and Array.from allows us to create a new, shallow-copied array. Unfortunately, Sets only enforce uniqueness for primitive values, but our list is full of objects.
Instead, we can do something like this.
const map = new Map();
list.forEach(item => {
map.set(item.name, item)
});
const uniqueList = Array.from(map.values())
Notice we’re using a Map here. Since Maps preserve insertion order, our uniqueList will have the same order as the original list, but without the duplicates since we’re using name as the key.
Another fancy approach is using filter with findIndex,
const uniqueList = list.filter((item, index) =>
list.findIndex(({name}) =>
name === item.name
) === index
);
Or using .reduce and .map,
const uniqueList = Object.keys(
list.reduce((acc, cur) => {
acc[cur.name] = cur.name;
return acc;
}, {}),
).map((name) => ({ name }));
Or one of the other various ways that I’m sure you’ll all let me know about 🫶.