mailwal

Remix Newsletter #47 | Remix 3 is Stable

Remix

Remix Newsletter #47

Remix Newsletter #47, October 2026, listing Remix 3 is Stable, Remix 3 in Action, Remix Jam 2026 Recap, and React Router v8.5.0 above a garage door marked with the Remix 3 Racing Team logo

Remix 3 is officially stable! We shipped [email protected] the night before Remix Jam, then spent the next day in Toronto showing it off. This issue covers the launch, our experience putting Remix 3 through it's paces on the Remix Store, and an overview of the Jam talks. Plus, we shipped React Router v8.5.0!

Let's hit it 🏎️


Remix 3 is Stable

Remix 3 has been large and long term effort. That's no surprise to you if you've been reading these newsletters for a while. We landed the first commit in July 2024. Now 2,600+ commits, 21 prereleases, and 53 contributors later, Remix 3 is ready for production, and it finally feels the web framework we've always wanted it to be.

Remix 3 is a full-stack web framework built on Web APIs, shipped as a single remix package. Everything is designed to work together, and every piece is also shipped as its own package, so you can use as much or as little as you want. Here's everything included:

  • Server: Typed routes, middleware, and controllers. A standard Request comes in and a standard Response goes out.
  • Data: SQLite, PostgreSQL, or MySQL with schemas, migrations, queries, validation, and file uploads.
  • Auth: Credentials or OAuth providers like GitHub, server-side sessions, and middleware to protect routes.
  • Assets: TypeScript, JSX, and CSS compile when requested, in development and production. No build step required.
  • Components: JSX rendered on the server, with only the parts you choose hydrated in the browser.
  • UI: Headless, accessible components and mixins like menus, popovers, comboboxes, selects, and tabs, plus spring-based animations. You have to install @remix-run/ui separately for now, as we're finalizing a few APIs before folding it into remix/ui.
  • Testing: Server, real browser, and end-to-end tests, all from remix test.

To start a new app, run npx remix new my-app, then follow along with the getting started guide, or just ask your agent to build you something with Remix 3.

Get started with Remix 3 ↗


Remix 3 in Action

Bar chart comparing the Remix Store before and after moving to Remix 3: store JavaScript down 58% from 500 KB to 210 KB, product page weight down 41% from 839 KB to 497 KB, homepage first paint down 73% from 4.4s to 1.2s, and runtime dependencies down 76% from 17 to 4

Even if you're excited about Remix 3, you may still find yourself asking "do we really need another framework?" It's a fair question, and quite honestly we don't have much interest working on a framework if we don't think it's faster, simpler, and more fun to build with (even if your letting agents do most of the programming).

For that reason we've been putting Remix 3 through it's paces. One real world example from our team was migrating the Remix Store from React Router 7 to Remix 3. Part of what made it so easy was the new Hydrogen toolkit, which provides framework-agnostic helpers for building Shopify storefronts and fit right into Remix 3.

Only 13 components on the whole site hydrate in the browser, like the cart and the add to cart button. Everything else is plain HTML. We tested the old and new stores on an emulated mid-range phone with throttled 4G and a slowed down CPU:

  • Less than half the JavaScript: The store's own JS dropped from about 500 KB to 210 KB (uncompressed).
  • 50-60% less time running scripts on every page we tested.
  • About 40% lighter pages: The product page went from 839 KB to 497 KB.
  • Faster first paint: The homepage paints in 1.2s instead of 4.4s.
  • 17 runtime dependencies down to 4: React, Radix, Tailwind, Zod, and our carousel library are all gone.

The Remix Store isn't the only site benefiting from Remix 3. Shopify Editions is rebuilding on it too, and Josh covers it in the Jam recap below.

Check out the Remix Store source ↗


Remix Jam 2026 Recap

Remix Jam Toronto 2026 backdrop with the Remix Jam logo in the center, surrounded by a repeating pattern of Remix and Shopify logos on a blue gradient

Thank you to everyone who joined us at the Shopify Toronto office and on the livestream! It was a blast to finally celebrate Remix 3 together.

All six talks are now on YouTube. Here's what each one covers.

Remix 3

In a world where agents write most of the code, Michael argued we should expect a lot more from a web framework. That's the idea behind Remix 3: make every piece faster, smaller, and easier to use, from the server to the browser, for you and your agents. He told the story of how a file upload parser built on web primitives grew into an entire framework, then walked through plain JavaScript state, mixins, and Frames with plenty of live coding.

Remix Unbundled

What if you could skip the bundler build step and start your production server immediately? Mark showed how the Remix asset server compiles TypeScript, JSX, CSS, and static files when they're requested, doing a bundler's jobs (compiling, preloads, HMR, minification, fingerprinting) one file at a time. He also showed off the fine-grained caching this enables: after editing one file inside an installed package, only that 2.2 KB file downloaded on refresh while everything else stayed cached.

Beyond the Server: Frames, SPAs, and Testing in Remix

A full-stack framework shouldn't stop at the server boundary. Matt showed how Remix extends up into the browser and out into the test runner by building the same app three ways: granular frames, the whole document as one frame, and a SPA with the router running entirely in the browser. The controllers in the last two are identical, character for character. He finished by running server, browser, and end-to-end tests from a single command.

How Do Agents Experience Remix?

Brooks traced the feedback loop between coding agents and Remix: what agents reveal about the framework, where they get stuck, and how those lessons reshaped real Remix APIs. He took on two myths: that models only know React and that agents don't benefit from using a framework. He ended the talk by building Snake in Next.js, React Router, and Remix to compare. Next.js and React Router finished faster, but Remix came back with a real database with migrations, robust auth (not hand-rolled AI slop of questionable security), and game logic in plain JavaScript, all with a whole lot less "hook-script."

The Remix Way

What happens when you apply the ideas behind Remix to everything you build? After moving seven apps to Remix 3, Sergio grew an entire stack around it, writing 88 packages covering i18n, background jobs, email, MCP, and UI components. His big takeaway is that Remix ships contracts, not just implementations, so swapping Resend for Cloudflare Email was a one line change. He even had Claude post a job to his demo app live on stage.

What Should the Browser Actually Own?

Every Shopify Edition asks the browser to do more, with WebGL scenes, video, and animation. Josh told the story of how his team started asking it to do less. He showed how they're rebuilding Editions on Remix 3 without React, keeping finished HTML as HTML and lazy loading heavy animations through Frames.

As Josh put it in his talk: "The goal isn't zero JavaScript. The goal is to be much more intentional about where that JavaScript lives." Remix gives you the controlls to be that intentional.

Watch the full Remix Jam 2026 playlist ↗


React Router v8.5.0

React Router v8.5.0 introduces a few unstable features for apps that want more control over how routes and data load, fixes a 11 bugs, and deprecates it's own View Transition APIs in favor of React's built in <ViewTransition> component.

Deprecations

React Router's view transition APIs are deprecated in favor of React's <ViewTransition> component, which is available in React 19.3 and later. This includes the viewTransition prop and option, useViewTransitionState, and the isTransitioning render prop and transitioning class on NavLink.

The existing APIs will continue working in v8 and will be removed in v9 (estimated release mid-2027). To switch, wrap <ViewTransition> around an <Outlet> in a persistent layout, and make sure you haven't set useTransitions={false} on your router. The view transitions migration guide has examples and compatibility notes.

Unstable Features

8.5.0 bring a few new nice unstable APIs. Adopt in production at your own risk, as we are still testing, receiving feedback, and may tweak the APIs. Please share any feedback on the linked RFCs.

API-only Framework Mode: Set ssr: "unstable_api-only" to serve static HTML (say, from a CDN) while keeping a runtime server for loaders, actions, revalidation, and route discovery. Prerendered pages hydrate from build-time data, and a SPA fallback handles everything else. The complimentary unstable_apiServerOrigin config lets you run the API on a different origin from your static HTML (just configure CORS and allowedActionOrigins). See the docs and RFC for more info.

Custom route discovery: The new future.unstable_customRouteDiscovery flag and unstable_useRouteDiscovery hook give your app control over lazy route discovery. Discover specific routes with discoverRoutes(paths), load the full route manifest with loadAllRoutes(), or decide how to recover from a manifest mismatch with onManifestMismatch. See the docs and RFC for more info.

Custom fetch for <HydratedRouter>: The new unstable_fetch prop lets you customize the manifest and server data fetch requests React Router makes in Framework Mode. Each call tells you what triggered it (initialization, navigation, fetcher, revalidation, or manifest), so you can add headers, set fetch options, retry safely, or inspect response headers. See the docs and RFC for more info.

Bug Fixes & Improvements

  • <Await> server renders promises decoded from an RSC payload instead of falling back to client rendering
  • The HydrateFallback of a route found through patchRoutesOnNavigation now renders during initial hydration
  • RouterProvider recovers router state when updates happen before it subscribes, and no longer replays server errors during hydration
  • fetcher.reset() stops revalidation, so cleared data no longer comes back
  • matchPath correctly treats optional static segments as optional when they contain characters outside [\w-]
  • An RSC server no longer crashes when a client aborts a document request mid-stream
  • Critical CSS collection in dev no longer triggers dependency re-optimization and full page reloads
  • Prerendering no longer fails intermittently with ECONNREFUSED errors
  • @react-router/express keeps the port when the Host or X-Forwarded-Host header is an IPv6 address
  • @react-router/node file sessions are written atomically, so concurrent commits can't corrupt them
  • @types/react and @types/react-dom are now optional peer dependencies, so types resolve under strict (non-hoisted) node_modules layouts

Check out the React Router changelog ↗


If you enjoy getting this email, please let us know! We'd love to hear from you, what you like about Remix and these updates, and any suggestions you have to improve them.

- The Remix Team

twittergithubdiscordyoutube

Docs · Blog

85 10th Ave, Floor 8, New York, NY 10011