Today’s issue: Cloudflare calls out Perplexity, CSS and Tailwind become BFFs, and developers discover the power of kratom-based productivity tools.
Welcome to #414.
Vercel's new Head of AI, reporting for duty
When Vercel first launched AI SDK
two years ago, it seemed like it might be just another half-baked attempt by a devtool company to jump on the AI gravy train.
But since then, “the AI toolkit for TypeScript” has grown to 2 million weekly npm downloads and quickly become a go-to library for developers building AI-powered apps.
Why tho? Because it gives you a clean abstraction over all the hairiest parts of working with LLMs – streaming, tool calling, persistence, and switching between models. It also works with every major UI framework and offers extreme robust type safety.
They just released AI SDK 5 last week, and it doubles down on all of that. Here are the biggest highlights:
Agentic loop control: New primitives like stopWhen
and prepareStep
let you build multi-step agents with greater control – define when your agent stops, switch models mid-loop, or force specific tool usage step-by-step.
Tool improvements: A new outputSchema
enables type safe tool outputs on the client, and the dynamicTool
function lets you define rules at runtime, which is helpful when inputs/outputs aren’t known in advance.
Redesigned chat with full-stack type safety: They rebuilt the useChat
hook from the ground up with typed message streams, structured parts (like tools and metadata), and a clean separation between UI and model messages for less front-end spaghetti code.
Bottom Line: Vercel has already cemented Next.js as the de facto way to build full-stack React apps. Now they’re starting to do the same for AI-powered apps, which might prove to be an even bigger and more important market over the next decade.
Never bet against the goth kids.
![]() ![]() ![]() ![]() |
Seeing new bugs in prod right after shipping a 'bug fix release'
Turns out, manually testing your team’s mobile app on a couple dusty iPhones isn’t exactly “best practice.”
It slows down release cycles, lets bugs slip through, and wastes your engineers’ time.
QA Wolf’s AI-native testing service fixes that. You’ll get 80% automated test coverage in weeks, with tests running on real iOS devices and Android emulators:
Schedule a demo to learn more – and see how they help customers do 5x more releases than they did before QA Wolf.
They just introduced AI Agent Monitoring to help you prevent errors, optimize your LLM costs, and understand the full picture when something in your AI agent breaks.
We have an existing filterRecommendations
function that takes two arguments:
purchasedProducts
: A list of product IDs that a user has already purchased.potentialRecommendations
: A list of product IDs that could be recommended to the user, which might include some products they have already purchased.The goal is to generate a list of unique product recommendations, ensuring that products the user has already purchased are not included.
Given that information, how can this code be improved?
function filterRecommendations(purchasedProducts, potentialRecommendations) {
return potentialRecommendations.filter(
(product) => !purchasedProducts.includes(product)
);
}
// Testing the function
console.time("Recommendations");
const purchasedProducts = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const potentialRecommendations = [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
const result = filterRecommendations(
purchasedProducts,
potentialRecommendations
);
console.log(result); // [11, 12, 13, 14, 15]
console.timeEnd("Recommendations"); // 0.34814453125 ms
Jared White wrote about how CSS and Tailwind are finally friends at last. Just like how I’m finally friends with my old high school nemesis who has apparently been quietly working at Figma for the last 7 years. It’s so nice to reconnect with old classmates without any sort of pretext or personal agenda.
Take Postman’s State of the API Survey. Thousands of developers have already shared how the world of APIs has changed. Join them and you’ll be entered to win an iPad Pro with all the accessories. [sponsored]
Colton Voege wrote about how AI is not actually making engineers 10x more productive. Only a potent blend of gas station kratom and disapproval from a father figure can do that.
Waku (a minimal React framework focused on RSC) now has Vite RSC support.
Una Kravets wrote about creating a scroll-spy with 2 lines of CSS. But if you want a scroll-manchurian-candidate, you’re still gonna need to use Tailwind.
React Universe Conf just published their full agenda, featuring Nicola Corti and Riccardo Cipolleschi from Meta co-hosting the keynote, plus new speakers from Amazon and HelloFresh. Matt Pocock will also be leading a Vercel AI SDK v5 workshop 🔥. Check it out. [sponsored]
Catherine Jue wrote about the power of fast software.
Speaking of which, Ryan Skinner wrote about how he built a full-stack React framework that’s 4x faster than Next.js with 4x more throughput. Tim Neutkens, you have 24 hours to respond.
CodeRabbit’s free VS Code extension gives you line-by-line AI code reviews right in your IDE. It’s like having a senior developer who understands the context of your whole codebase give you feedback on every line of code and provide one-click fix suggestions. [sponsored]
TkDodo wrote about React Query selectors, supercharged.
Jean Boussier wrote about what’s wrong with the JSON gem API. We all know that Ruby is objectively inferior, but this post does have some interesting insights on API design.
Cloudflare called out Perplexity for using stealth, undeclared crawlers to evade website no-crawl directives – which gave me flashbacks to being called out by the manager of my local 7-11 for wearing multiple disguises into the store on July 11th to get eight free slurpees. And I would’ve gotten away with it too, if it weren’t for those meddling kids.
function filterRecommendations(purchasedProducts, potentialRecommendations) {
return potentialRecommendations.filter(
(product) => !purchasedProducts.includes(product)
);
}
We can improve this code by using a Set
to store the purchasedProducts
list. Because Set
allows us to check for the existence of a value in constant time, we can avoid the linear time lookup that Array.includes
requires. In theory, this should make the function significantly faster for large lists of products (but you should always benchmark your code to be sure).
function filterRecommendations(
purchasedProducts,
potentialRecommendations
) {
const purchasedProductsSet = new Set(purchasedProducts);
return potentialRecommendations.filter(
(productId) => !purchasedProductsSet.has(productId)
);
}
console.time("Recommendations");
const purchasedProducts = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const potentialRecommendations = [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
const result = filterRecommendations(
purchasedProducts,
potentialRecommendations
);
console.log(result); // [11, 12, 13, 14, 15]
console.timeEnd("Recommendations"); // 0.212890625 ms