Today’s issue: Conventionally attractive JavaScript functions, extreme prefetching, and fun ways to gaslight your users.
Welcome to #402.
Some Rome devs drink to remember, others drink to forget
Much like my gut micro-biome, the Biome toolchain project has been through a lot the past few years.
It first launched as Rome back in 2020, calling itself “the spiritual successor to Babel” and raising $4.5 million in VC, before ultimately flaming out a couple years later in semi-dramatic fashion.
But Emanuele Stoppa and a few other Rome maintainers didn’t want to see all that precious Rust code go to waste, so they forked the project in August 2023, renamed it Rome 2 Biome
, and started building.
Fast forward to today, and Biome is thriving like the forest in Fern Gully after all the fairies killed that toxic sludge monster.
The team has released a blazing formatter and linter that work interactively within your IDE, their weekly npm downloads have 4x’d in the last year, and they just launched Biome v2 with some powerful upgrades.
Let’s take a closer look at what’s new:
Type-aware lint rules – Biome can now lint your TypeScript code without needing the tsc
compiler or the typescript
package. That’s because it includes its own lightweight type inference engine, which makes linting faster, easier to configure, and less TypeScript-y.
Multi-file analysis – Biome now comes with a file scanner that scans and indexes all the files in your project. This enables more complex rules powered by Biome’s new type inference engine, though it may come with a slight performance trade-off in some cases.
Linter plugins – Biome now supports GritQL plugins that let you match specific code patterns and register customized diagnostic messages for them. More robust plugins should come in future releases.
Bottom Line: Do I still get the occasional night terror about Hexxus, the animated sludge monster? No comment.
But the Biome team shows what we can accomplish if we bury our trauma down deep and use Rust to create build tools that heal the JS ecosystem – together.
![]() ![]() ![]() ![]() |
When you look under the hood at those charts you've been vibe-coding
They’re fast, customizable, and work seamlessly with any JavaScript framework.
That’s probably why the library gets over 1 million npm downloads per month, and is now used in thousands of enterprise applications.
Their gallery shows off dozens of chart options, but here’s a few of my personal favorites:
Interactive financial charts that let you interact with data in real time – so you can easily track the minute-by-minute value of your Funko Pop collection assets.
Customizable maps for visualizing data over geographic areas – so you can chart the relationship between Buc-ee’s locations and all those rolling blackouts.
Heatmaps that can chart everything from your team’s app performance, to your team members’ hairlines.
Use it for free – or check out the enterprise version for advanced features like animations, context menus, and more.
Their AI App Security Engineer uses static analysis and LLMs to eliminate all false positives, so your team only deals with *real* security issues. Loved by teams at Snowflake, GitLab, and Figma.
let seats = [
[1, 1, 0, 1, 0],
[0, 1, 1, 1, 0],
[1, 0, 1, 0, 0],
];
function reserveFirstAvailableSeat(seats) {
for (let i = 0; i < seats.length; i++) {
for (let j = 0; j < seats[i].length; j++) {
if (seats[i][j] === 0) {
seats[i][j] = 1; // Reserve the seat
console.log(`Reserved seat at row ${i + 1}, column ${j + 1}`);
break;
}
}
}
}
reserveFirstAvailableSeat(seats);
Surma wrote this in-depth article about using LangGraph for complex workflows and other goodies about LLM architecture.
Kadi Kraman wrote about simplifying auth flows in Expo Router with protected routes, so you can gatekeep-gaslight-girlboss your users more than ever.
Hono 4.8 comes with a new Route helper, new third-party MCP middleware, and reduced code size.
Apryse’s PDF webviewer is a powerful JavaScript SDK that lets you put document workflows directly in your application with features like annotation, search, form filling, and more. [sponsored]
Jake Archibald wrote about how to animate zooming using CSS. If you’re curious about how to get a zoomer animated, I suggest telling them that their vintage sweatshirt smells like a rat’s nest.
The Next.js team wrote a new guide to Prefetching that’ll help you load your entire site within 30 seconds of your user waking up in the morning.
Joeri Sebrechts wrote about bringing React’s <ViewTransition>
to vanilla JS.
CarbonQA provides QA services for dev teams, so you’ll never have to QA test your own app ever again. They work in your tools, talk with your team on Slack, and let your devs be devs. [sponsored]
Ryan Toronto wrote about composable streaming with <Suspense>
Type Buddy lets you hover over your complex types to reveal the beautiful function underneath. Like when the love interest in a romcom takes off their glasses and everyone realizes they actually were conventionally attractive all along.
The code ends up making 3 reservations instead of 1. This is because the break
statement only breaks out of the inner loop, not the outer loop. To fix this, you can replace the break
statement with a return
statement.
let seats = [
[1, 1, 0, 1, 0],
[0, 1, 1, 1, 0],
[1, 0, 1, 0, 0],
];
function reserveFirstAvailableSeat(seats) {
for (let i = 0; i < seats.length; i++) {
for (let j = 0; j < seats[i].length; j++) {
if (seats[i][j] === 0) {
seats[i][j] = 1; // Reserve the seat
console.log(`Reserved seat at row ${i + 1}, column ${j + 1}`);
return;
}
}
}
}
reserveFirstAvailableSeat(seats);
Alternatively, you can use labeled statements to explicitly break out of the outer loop:
let seats = [
[1, 1, 0, 1, 0],
[0, 1, 1, 1, 0],
[1, 0, 1, 0, 0],
];
function reserveFirstAvailableSeat(seats) {
rows: for (let i = 0; i < seats.length; i++) {
columns: for (let j = 0; j < seats[i].length; j++) {
if (seats[i][j] === 0) {
seats[i][j] = 1; // Reserve the seat
console.log(`Reserved seat at row ${i + 1}, column ${j + 1}`);
break rows;
}
}
}
}
reserveFirstAvailableSeat(seats);