TanStack Start gets RSC

Issue #478.April 14, 2026.2 Minute read.
Bytes

Today’s issue: Saving tokens with ancestral tenets, why AI sucks, and casual xenophobia.

Welcome to #478.


Eyeballs logo

The Main Thing

A dude pretending to be a parrot

The 20k LoC app that Codex built to check the price of fartcoin

TanStack Start gets RSC, but not like Next.js

While Cloudflare and others have been busy trying to clone Next.js with AI, TanStack Start is basically the only project that’s been willing to ask if there’s a better way to build a React framework from scratch in 2026.

So it makes sense that when they shipped experimental support for server components yesterday, it came out looking like “what if Next.js but opposite?” It’s a bold move since Vercel helps steward React itself and also helped create RSC to sell more cloud compute make the web a better place.

In Next.js, the server owns your component tree by default. You opt into interactivity with 'use client', not the other way around. TanStack Start treats RSC as plain React Flight streams you can fetch, cache, and render on your own terms, like any other async resource.

const getGreeting = createServerFn().handler(async () => {
  return renderToReadableStream(<h1>Hello from the server</h1>)
})

function Greeting() {
  const query = useQuery({
    queryKey: ['greeting'],
    queryFn: async () =>
      createFromReadableStream(await getGreeting()),
  })
  return <>{query.data}</>
}

RSC output slots right into TanStack Query with normal cache keys, staleTime, and background refetch, with no special “RSC mode” required. Here’s a few other notable differences from Next.js:

  • Client owns the tree. Server components are fetched by the client rather than server-rendered by default

  • Better security. Instead of 'use server' actions, it uses explicit server functions via createServerFn only, which would avoid recent RSC CVEs

  • Composite Components. A new primitive that lets the server leave slots for the client to fill with interactive components, without knowing what goes in them

  • Fully opt-in. Pure SPA, hybrid, mostly static, fully static. It turns RSC into a tool instead of a mandate for your whole app

On tanstack.com’s own content-heavy pages, migrating to RSC dropped ~153KB gzipped from the client bundle and cut Total Blocking Time on the blog post page from 1,200ms to 260ms. Dashboards and interactive-heavy pages saw little to no improvement.

Bottom line: JavaScript framework innovation has slowed to a crawl as AI has cemented the incumbents and sucked up all the air in the room. So it’s refreshing to see Tanner & Co. ship something actually new that has a genuine chance of grabbing real market share.


QA Wolf logo

Our Friends
(With Benefits)

Martin Scorsese lying on a bed

When it takes longer to test the code than to write the code

How to set up AI-powered QA for daily releases - free webinar

AI fundamentally changes how software gets built. Faster developers are building more features and opening more PRs than ever before… but QA is still the bottleneck.

Join QA Wolf co-founder & CEO Jon Perl for a live webinar to see how QA Wolf’s AI-powered testing platform equips teams for an AI-native SDLC.

You’ll see:

  • Mapping AI that autonomously maps app workflows
  • Automation AI that generates deterministic, code-based tests
  • Parallel runs that return results in minutes

RSVP here - and see how much better this is than telling Codex to “write some tests.”


Pop Quiz logo

Pop Quiz

Sponsored by Sentry

Next.js runs in three runtimes, but most loggers only cover one. This blog post shows how you can use LogTape and Sentry to get runtime-agnostic logging across all of them.

What will be logged to the console when this code executes? The answer is below.

window.name = "Mike Tyson";

const me = {
  name: "Tyler",
  sayName() {
    console.log(this.name);
  },
};

const sayName = me.sayName;
sayName();

Cool Bits logo

Cool Bits

  1. Caveman is a Claude Code skill that cuts token usage by 65% by telling it to talk like a caveman. Also very beneficial for the companion app I’m creating that’s designed to make users fall in love with various GEICO spokespeople through the years.

  2. Bun v1.3.12 ships with a native headless browser automation built into the runtime.

  3. How to stop babysitting your agents. Agents can generate code. Getting it right for your system is the hard part – you end up wasting time and tokens in correction loops. Join Unblocked for a FREE webinar on April 23 to see how to give agents exactly what they need to generate mergeable code the first time. [sponsored]

  4. Adam Argyle wrote about why AI sucks at frontend. Looking forward to his followup piece on why you suck at frontend.

  5. James Coglan wrote about uses for nested promises.

  6. Now you can build iOS home screen widgets and Live Activities as React components. No separate Xcode target. No manual App Groups. No SwiftUI layout code necessary. [sponsored]

  7. Jack wrote about his experience installing every Firefox extension. Oh you use Firefox? Name every extension.

  8. Polypane wrote about the best browser API you’re not using. It’s the new(ish) Intl API, and the only reason you’re not using it is because you hate people from other countries, admit it.

  9. Digital Experience Monitoring Solution Brief is an in-depth resource that walks you through how frontend teams are using Datadog as a single source of truth to run synthetic tests against different environments, devices, and browsers. [sponsored]

  10. Rene wrote about how attackers hid obfuscated malware in PRs to the Better-Auth library.

  11. We wrote this very cool guide to imperative vs declarative programming.

  12. Aaron Harper wrote about how you can’t cancel a JavaScript promise (except sometimes you can). I’m not totally sure, but this sounds very familiar to a conversation I blocked out of my memory after my college girlfriend told me we need to talk.


Pop Quiz logo

Pop Quiz: Answer

Sponsored by Sentry

What will be logged to the console when this code executes?

window.name = "Mike Tyson";

const me = {
  name: "Tyler",
  sayName() {
    console.log(this.name);
  },
};

const sayName = me.sayName;
sayName();

The answer? “Mike Tyson”.

Since we’re not in strict mode, sayName isn’t a method, and we’re not using call or apply, this inside of sayName will default to the window object.