React 19.3

Issue #521.September 15, 2026.2 Minute read.
Bytes

Today’s issue: A cure for cache-poison, Meta’s cannabis-infused database proxy, and how a hint of Marxism could fix open source.

Welcome to #521.


Eyeballs logo

The Main Thing

An exhausted jogger bent over with hands on knees catching their breath

React having its own millennial midlife crisis

React 19.3

While most of the world was debating if AI is going to kill us all in the next 10 years, the React team quietly shipped React 19.3. So like the good ol’ days when all we had to worry about was a rogue useEffect taking down the internet, we’re back to writing about React.

My first observation, as someone who watched a little too much TMZ back in 2005, was that there appears to have been a bit of a shakeup to the team structure, and some clues on where the project might be going in the future.

Project Updates:

In addition to some of the OGs (Sebastian Markbåge and Joe Savona) leaving the project, the project now seems to be organized around 4 pillars: Server, DOM, Fiber, and Compiler. While this could have been the case for a while and I’m just now noticing, it does signal that the project is stabilizing and it’s unlikely to see any wild paradigm-changing shifts - a la hooks and RSC (especially now that Seb is gone). I think that shows up in this release where features that have been in the works for over a year are finally being released.

What landed in 19.3:

  • ViewTransitions: This new component allows you to animate elements as they enter, exit, move or resize using built-in support for the browser’s View Transition API. Please be warned, you will still need to write CSS.

  • Fragment Refs: Fragment refs allow you to access the DOM of the Fragment’s children, allowing you to set up event listeners, manage focus, and observers without needing an extra DOM element.

  • Client / Server updates: Now you can use Context directly in server components and pass data to your context like this.

// server-component.js
import { UserContext } from './user-context';

export async function Layout({ children }) {
  const currentUser = await getCurrentUser();

  return (
    <UserContext value={currentUser}>
      {children}
    </UserContext>
  )
}

Bottom line: React is starting to look like a middle-aged millennial that moved to the suburbs, but Guillermo is probably still pondering its implications (at least for a few more months).


Sonar logo

Our Friends
(With Benefits)

A man wearing an extremely long necktie that trails far below his waist

When you catch CVEs but miss that your app allows stacked discounts

SonarQube Hunter Agent: Your On Demand Security Researcher

Static analysis and algorithmic testing are essential tools for finding vulnerabilities like SQL injections or known CVEs, but they don’t understand your application’s context or business intent.

That’s why Sonar created SonarQube Hunter Agent, an automated security researcher that explores your codebase and finds the issues you’ve probably missed.

It comes with:

  • Intent-based vulnerability detection: It finds costly business logic flaws like stacked coupons or missing rate limits, and protects your app from privilege escalation bugs

  • Consistent, auditable findings: Hunter Agent is designed to deliver reproducible results that teams can review, prioritize, and act on with confidence

  • Seamless Integration: You can run Hunter Agent analyses on demand or on a schedule, then review findings in SonarQube with clear context and guidance for fixing them

Try SonarQube Hunter Agent today – it’s already surfaced over 200 zero days in open source projects.


Spot the Bug logo

Spot the Bug

Spot the Bug – Sponsored by Orkes

It’s an open-source agentic workflow platform that lets you easily build agents and workflows, run them durably, and observe and control them through every step. Used by Netflix, Tesla, LinkedIn, and more.

const products = {
  SKU12345: { name: "Laptop", price: 999, discount: 0.1 },
  SKU67890: { name: "Phone", price: 499, discount: 0 },
  SKU54321: { name: "Tablet", price: 299, discount: 0.05 },
};

function printFormattedProductDetails(products) {
  for (const product in products) {
    const { name, price, discount } = product;

    let finalPrice = price;
    if (discount) {
      finalPrice = price - price * discount;
    }

    console.log(
      `Product: ${name}, Price: ${finalPrice.toLocaleString("en-US", {
        style: "currency",
        currency: "USD",
      })}`
    );
  }
}

printFormattedProductDetails(products);

Cool Bits logo

Cool Bits

  1. Fatih Arslan wrote about how he manages his agents, a post you’ve read a million times, but this time from an engineer at Cursor who actually knows what he’s doing.

  2. It only took Shopify 12 weeks to migrate the Shop app from React Native to Swift/Kotlin leaving the React Native Stans in shambles.

  3. Only idiots write manual tests – modern engineering teams like Notion, Dropbox and LaunchDarkly use Meticulous to maintain e2e UI tests that cover every edge case of your web app. [sponsored]

  4. Vercel made a cool website to showcase their R&D projects that their “Labs” team has been working on.

  5. Lovable used oj to improve their preview sandbox cold starts from 4.9s with vite to 1.2s and reduced their memory usage by 84%.

  6. The engineers at Meta wrote a post about ZGateway and proxying traffic to ZippyDB. I’m pretty sure I saw a billboard for a cannabis store that was selling ZippyDBs. Coincidence?

  7. Convex created an official set of plugins for AI agents that includes skills, custom agents, MCP integrations and more to help you build better apps. [sponsored]

  8. Laurie Voss cracked the code for how to get everyone paid in open source. Private registries with a hint of Marxism are VERY on brand.

  9. GitHub Actions added cache-mode to save you from cache-poisoning.

  10. Dominic Gannaway removed lazy destructuring from tsrx which means we’re only a few more cuts away from it going back to just being JSX.


Spot the Bug logo

Spot the Bug: Solution

Spot the Bug – Sponsored by Orkes

The for ... in loop iterates over the keys of the object, not the values. This results in a TypeError. To fix this, we need to access the value of the key in the object.

const products = {
  SKU12345: { name: "Laptop", price: 999, discount: 0.1 },
  SKU67890: { name: "Phone", price: 499, discount: 0 },
  SKU54321: { name: "Tablet", price: 299, discount: 0.05 },
};

function printFormattedProductDetails(products) {
  for (const product in products) {
    const { name, price, discount } = products[product];

    let finalPrice = price;
    if (discount) {
      finalPrice = price - price * discount;
    }

    console.log(
      `Product: ${name}, Price: ${finalPrice.toLocaleString("en-US", {
        style: "currency",
        currency: "USD",
      })}`
    );
  }
}

printFormattedProductDetails(products);