The Vercel Homophone

Issue #294.June 3, 2024.2 Minute read.
Bytes

đź”® For the past year we’ve been working closely with the React Query team to create query.gg, the new official React Query course.

It’s now available and for the next two days, both the new course and the subscription to all of our courses are 30% off.


Today’s issue: Getting over GraphQL, forking Kaboom.js, and finding a language that finally tolerates my faults.

Welcome to #294.


Eyeballs logo

The Main Thing

Mona Lisa dabbing

When you fix the caching bug that used to be a feature

Next.js 15 fixes caching

If I had to use one word homophone to describe last week’s Vercel Ship conference, it would be cashing/caching.

During the keynote, Guillermo revealed that Vercel has been cashing those enterprise checks (to the tune of $100m in annual revenue), and LeeRob revealed how the new Next.js 15 RC comes with some major caching improvements. Let’s dive into those.

Quick review: Next’s App Router initially came with opinionated caching defaults designed to provide “the most performant option.” This sounds great in theory, but it’s a pain to deal with when working with a third-party library that uses fetch (along with a few other common scenarios).

Developers have complained about this for the past few months – but rather than trying to gaslight educate everyone about why they were wrong, the Next team chose to listen to the feedback and make caching a little less aggressive.

In Next.js 15, fetch requests, GET Route Handlers, and client navigations are no longer cached by default. But you can always opt into caching if you prefer it that way.

A few more highlights from v15:

  • A new experimental_ppr route config option that allows you to incrementally adopt Partial Prerendering

  • React 19 RC support and experimental React Compiler support

  • Updated create-next-app design and a new --turbo flag to enable Turbopack in local development

Bottom Line: JavaScript frameworks are constantly trying to balance the tradeoffs that come with being more vs less opinionated. This release definitely shifts Next.js towards being a little more hands off, which is probably a good call as it becomes increasingly ubiquitous.

        

FusionAuth Logo

Our Friends
(With Benefits)

A skeleton admiring the clothes of medieval person

"You built all of this in an hour? Incredible."

Need auth for your Angular app? Try FusionAuth

They give you a scalable solution with awesome DX – and their Angular Quickstart helps you get set up in under 5 minutes.

You can easily customize anything you want from there, using their next-level auth and security features:

  • Customizable hosted pages for login, registration, forgot password, and more

  • Password rules and hashing algorithms to meet your security needs

  • SSO, MFA, login, and a bazillion other features you can set up in days, not months

Use the Angular Quickstart to build a working app – and if you send them a screenshot, they’ll send you this free t-shirt 🔥.


Spot the Bug logo

Spot the Bug

Sponsored by Apryse

Their cross-platform SDK helps you generate reports, invoices, letters, and contracts in PDF format with JSON data directly within the browser or from a server.

class ChatApp {
  constructor() {
    this.keywordRegex = /hello|hi|hey/g;
  }

  receiveMessage(message) {
    if (this.keywordRegex.test(message)) {
      this.sendGreeting();
    }
  }

  sendGreeting() {
    console.log("ChatApp: Hello, how can I assist you today?");
  }
}

let chatApp = new ChatApp();

chatApp.receiveMessage("hi, how are you?");
chatApp.receiveMessage("hello, can you help me?");

Cool Bits logo

Cool Bits

  1. Ahmad Shadeed wrote an interactive deep dive on the pain points that CSS gap solves. I could write my own deep dive on the pain points that The Gap clothing store solved for me as a child in the late ’90s.

  2. CarbonQA provides high-quality QA services for your dev team. Their US-based testers work directly with your tools and will break your app repeatedly, so you never have to waste eng time on QA testing again. [sponsored]

  3. svgl is a beautiful library of SVG logos that’s built with SvelteKit and Tailwind CSS.

  4. Matt Bessey wrote about Why he’s over GraphQL, after 6 years. As my fortune cookie from Panda Express told me this morning, It’s better to have loved and lost, than to have never loved at all.

  5. KAPLAY is the new spiritual successor (and fork) of the Kaboom.js game library, after layoffs at Replit affected the original creator of Kaboom.

  6. Alan Smith wrote an article called On Constraints and Freedom about the lessons he learned from building component styling APIs. Lesson #1: when in doubt, don’t let your users make any choices.

  7. Jarek Samic and the 1Password team wrote about How they used esbuild to reduce browser extension build times by 90%.

  8. Rsbuild just released v0.7 of its Rspack-based build tool. This is the last minor release before v1.0, so get hyped, Rust-heads.

  9. Ives van Hoorne wrote about How Codesandbox scales their microVM infrastructure using low-latency memory decompression. It might not be the catchiest title, but it’s a great read.

  10. Gleam v1.2 was just released with “fault-tolerant compilation.” I must say, it feels great to finally have something in my life that tolerates my faults.


Spot the Bug logo

Spot the Bug: Solution

Sponsored by Apryse

chatApp.receiveMessage("hi, how are you?"); // "ChatApp: Hello, how can I assist you today?"
chatApp.receiveMessage("hello, can you help me?"); // Logs nothing

In JavaScript, RegExp objects with the g (global) flag retain state between matches due to the lastIndex property, which can lead to unexpected results when reused across different inputs.

The solution is to create a fresh RegExp object for each incoming message, ensuring proper recognition and response to all greetings.

class ChatApp {
  receiveMessage(message) {
    let keywordRegex = /hello|hi|hey/g;
    if (keywordRegex.test(message)) {
      this.sendGreeting();
    }
  }

  sendGreeting() {
    console.log("ChatApp: Hello, how can I assist you today?");
  }
}

let chatApp = new ChatApp();

chatApp.receiveMessage("hi, how are you?"); // "ChatApp: Hello, how can I assist you today?"
chatApp.receiveMessage("hello, can you help me?"); // "ChatApp: Hello, how can I assist you today?"