Hope you’re all surviving the cringiest day of the year. On the bright side, there’s only a few hours to go until all your favorite dev influencers stop posting derivative April Fools jokes as engagement bait, and go back to posting… derivative web dev takes as engagement bait. Just like nature intended 🧘♂️.
Today’s issue: Mainlining your CSS, Morbius-style 3D rendering, and a major TC39 proposal enters the chat.
Me waiting patiently for Bun to come to my window(s)
Bun just launched v1.1 earlier today, and it’s a huge release.
We finally get full Windows support, which means that Bun’s runtime, test runner, package manager, and bundler all work on Windows now. And because it’s Bun, they’re all fast af. Here’s a few quick stats:
When installing a Vite React App, Bun’s package manager, bun install
runs 18x faster than yarn
and pnpm
and 30x faster than npm
on Windows.
bun run
is an 11x faster alternative to npm run
for running scripts. They made it even faster on Windows by creating a new .bunx
file format, which is a cross-filesystem symlink that can start scripts or executables using Bun or Node.js.
They’ve optimized lots of Node APIs to use the fastest syscalls available on Windows, significantly improving performance.
This Bun 1.1 launch video goes into a lot more detail on all the Windows updates. But when we watched it, we learned two surprising, yet important facts: 1) Jarred Sumner’s buttery-smooth baritone is perfect for ’90s action-movie trailers, and 2) there’s a lot more to this release than just Windows support.
In Bun 1.1, Bun is now a cross-platform shell like bash that works seamlessly across Windows, Linux, and macOS, without requiring any additional dependencies. It comes with familiar features like redirection, pipes, and environment variables — but it also introduces new features like a built-in Glob API and enhanced JavaScript interop.
This release also improves Bun’s Node.js compatibility with new fixes and improvements to Node APIs and new support for npm packages like playwright, puppeteer, and tensorflowjs. Bun still aims to be a drop-in replacement for Node, and the Bun team has said that “if it works in Node.js but not in Bun, it’s a bug in Bun.”
Bun 1.1 also introduces lots of other speed and performance upgrades, but there are only so many ways we can write, “Bun is 100x faster than [insert build tool]
” — so go check out the announcement post if you want more specifics.
Bottom Line: **Jarred Sumner voice** In a world where new JavaScript runtimes pop up every other weekend, there’s still one team that’s shipping new updates faster than the rest. But will Bun be able to do enough to knock Node.js off its throne? Stay tuned.
What it feels like to finally use RSC for the first time.
Their component gives you an experimental implementation of a grid that uses React Server Components to seamlessly blend server-side and client-side operations, enabling cool features like:
Next-gen data binding where you can use RSC to start rendering your component before having your data (see demo)
Fundamental data operations like filtering, sorting, and paging, which can be performed either on the client side or server side. By using hybrid data operations, you can easily define whether specific actions should occur on the server or on the client.
Powerful data editing capabilities with flexible configuration options for row editing and cell editing for your application
Check out the KendoReact Server Grid in your app today.
They created this Synthetic Monitoring solution brief, which shows you how to improve your site’s UX and reliability with a proactive monitoring platform.
function decodeBinaryCommands(binaryStrings) {
const commands = [];
for (let binStr of binaryStrings) {
const command = parseInt(binStr, 10);
switch (command) {
case 1:
commands.push("Start");
break;
case 2:
commands.push("Stop");
break;
case 3:
commands.push("Pause");
break;
case 4:
commands.push("Resume");
break;
default:
commands.push("Unknown");
break;
}
}
return commands;
}
const binaryCommands = ["0001", "0010", "0100", "0011", "1100"];
const decodedCommands = decodeBinaryCommands(binaryCommands);
console.log(decodedCommands);
Evan Boehs wrote a helpful article on Everything he knows about the xz backdoor, so you can pretend to understand low-level security issues with more confidence than ever.
Alex Patterson wrote this deep dive on Best practices for OAuth in mobile apps, which shows how to improve your login experience, speed up development, and secure APIs for your applications. [sponsored]
Rob Eisenberg and Daniel Ehrenberg just submitted a TC39 proposal to add signals to JavaScript.
Microsoft Developer, Luciano Strika wrote about The unreasonable effectiveness of inlining CSS. Personally, I’m more into mainlining my CSS, but do whatever works for you.
Daniel Roe and Sébastien Chopin wrote about Their plans for the Nuxt project in 2024.
JS-Torch is a deep learning JavaScript library patterned after PyTorch with a fully functional Tensor object, deep learning layers and functions, and an automatic differentiation engine. Watch your back, Lex Fridman.
Deno 1.42 was released last week with first-class support for their JSR registry and two new subcommands, deno publish
and deno add
.
Ollie Bannister wrote this deep dive on comparing JS runtime environments and package managers as part of Raygun’s JS Toolbox 2024 series. Perfect timing, Ollie 🙏. [sponsored]
Gulp v5 just came out, and it’s cool to see the Gulp team still doing their thing.
Maxime Heckel wrote this deep dive on Moebius-style post-processing and other stylized shaders, not to be confused with *Morbius-style shaders. But it’s always Morbin’ time in my book.
If we run this code, we get an output of ['Start', 'Unknown', 'Unknown', 'Unknown', 'Unknown']
. This is because the parseInt
function has the wrong radix. In this case, we want to use a radix of 2 to convert the binary string to a decimal number.
function decodeBinaryCommands(binaryStrings) {
const commands = [];
for (let binStr of binaryStrings) {
const command = parseInt(binStr, 2);
switch (command) {
case 1:
commands.push("Start");
break;
case 2:
commands.push("Stop");
break;
case 3:
commands.push("Pause");
break;
case 4:
commands.push("Resume");
break;
default:
commands.push("Unknown");
break;
}
}
return commands;
}
const binaryCommands = ["0001", "0010", "0100", "0011", "1100"];
const decodedCommands = decodeBinaryCommands(binaryCommands);
console.log(decodedCommands);