Making React Native actually native

Issue #467.March 4, 2026.2 Minute read.
Bytes

Today’s issue: Reblogging left-pad, the most illegal REPL, and getting fair compensation from Drizzle.

Welcome to #467.


Eyeballs logo

The Main Thing

TSA agent about to full body search a puppet

iOS devs checking if an app is *native* native

Making React Native actually native

For years, the biggest compliment you could give a React Native app was to say it feels “basically native.”

That eventually turned into a subtle diss from the mobile dev masochists purists, but last week’s SDK 55 comes with the stated goal of making React Native apps feel actually native and indistinguishable from apps built with Swift or Kotlin.

That’s a high bar, but here’s how they’re doing it:

  • Expo UI gets serious – The @expo/ui library now lets you use real SwiftUI and Jetpack Compose components directly from JavaScript. The Compose API graduated from alpha to beta with lots of new Material 3 components, and the SwiftUI component APIs were renamed to match SwiftUI conventions 1:1.

  • More native features in Expo Router v55 – A new Apple Zoom transition brings shared element transitions via the native iOS zoom gesture, and a new Stack.Toolbar API gives you declarative control over UIToolbar on iOS. There’s also a new Colors API for dynamic Material 3 styles on Android and adaptive colors on iOS.

  • expo-widgets for iOS (alpha) – Lets you build iOS home screen widgets and Live Activities using just Expo UI components with zero native code. It also gives you JS API based on shared objects for creating widget timelines, live activity management, and more.

Bottom Line: “Basically native” has already been good enough for thousands of Expo apps, but SDK 55 closes the gap to the point where even the most pretentious Swift developers won’t be able to tell the difference.


Atlassian logo

Our Friends
(With Benefits)

Wide eyed guy looking at coffee cup

Watching your agent hallucinate a whole new sprint

Rovo Dev helps you automate the tedious stuff

Atlassian designed their AI agent, Rovo Dev to carry full Atlassian context into all the places you already work - like your terminal, IDE, GitHub and more.

That means you can use it to:

  • Plan, generate, and review code without context switching - including multi-file implementations, config changes, and migrations

  • Kick off code plans directly from Jira, and plug into Bitbucket and GitHub for review

  • Enforce org-level standards across all repos with customizable reviews

Try it out for free – and stay in flow across your entire SDLC with Rovo Dev.


Spot the Bug logo

Spot the Bug

Sponsored by Clerk

Most coding agents suck at auth. clerk/skills fixes that, so your agent can handle everything from basic Next.js auth to complex custom flows and user sync.

const fetchPokemon = async (id) => {
  const response = await fetch(`https://pokeapi.co/api/v2/pokemon/${id}`);
  if (!response.ok) {
    throw new Error(`Network response was not ok: ${response.statusText}`);
  }
  const data = await response.json();
  return data;
};

const getStarterPokemon = () => {
  const ids = [1, 2, 3]
  const pokemon = [];

  ids.forEach(async (id) => {
    const result = await fetchPokemon(id);
    pokemon.push(result);
  });

  return pokemon
}

getStarterPokemon()

Cool Bits logo

Cool Bits

  1. Bun v1.3.10 comes with a new native REPL that’s written in Zig and is officially illegal in all US states and territories.

  2. Convex CEO, Jamie Turner wrote about why he doesn’t care about database benchmarks (and neither should you). [sponsored]

  3. Jakub and Hassan wrote a deeper dive on Expo Router v55 and how it provides more native navigation and more powerful web features.

  4. Solid.js v2.0 beta makes async first class, turns pending UI into an expression, and can make all your student loans disappear if you forward this email to six people before midnight.

  5. 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]

  6. Chrome’s new WebMCP is available for early preview. It brings two new APIs that allow browser agents to take action in HTML forms and complex JavaScript execution.

  7. npmx just launched the first alpha of their “fast, modern browser for the npm registry” with social features. I’m gonna reblog left-pad so hard.

  8. Shayon Mukherjee shared a deep dive on sandbox isolation.

  9. PlanetScale just bought Drizzle 🤑. And as someone who has written at least one newsletter story about the project, my disbarred lawyer uncle has informed me that I should be legally entitled to some compensation here.


Spot the Bug logo

Spot the Bug: Solution

Sponsored by Clerk

await-ing inside of a forEach will only end in pain. There are a few different ways to fix this, but here’s one using a for of loop.

const fetchPokemon = async (id) => {
  const response = await fetch(`https://pokeapi.co/api/v2/pokemon/${id}`);
  if (!response.ok) {
    throw new Error(`Network response was not ok: ${response.statusText}`);
  }
  const data = await response.json();
  return data;
};

const getStarterPokemon = async () => {
  const ids = [1, 2, 3]
  const pokemon = [];

  for (const id of ids) {
    const result = await fetchPokemon(id);
    pokemon.push(result);
  };

  return pokemon
}

await getStarterPokemon()