You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/routes/blog/post/remix-3-whats-changing-and-why-it-matters/+page.markdoc
+14-12Lines changed: 14 additions & 12 deletions
Original file line number
Diff line number
Diff line change
@@ -11,7 +11,7 @@ category: news
11
11
12
12
For a while, it seemed like Remix had reached a natural end. By late 2024, almost everything that made Remix unique, its loaders, actions, and nested routing, had been merged into React Router 7. The framework's creators, Ryan Florence and Michael Jackson, even joked that Remix 2 had become "React Router, the Framework." Many developers assumed Remix would fade away.
13
13
14
-
But in May 2025, the team [announced Remix 3](https://remix.run/blog/wake-up-remix), an unexpected rebuild from the ground up, meant to rethink how web apps are built. They showed early previews at [Remix Jam 2025](https://remix.run/blog/remix-jam-2025-recap), and while the final release is planned for 2026, the goals are already clear. Remix 3 breaks away from React entirely and rebuilds around web standards.
14
+
But in May 2025, the team [announced Remix 3](https://remix.run/blog/wake-up-remix), an unexpected rebuild from the ground up, meant to rethink how web apps are built. They showed early previews at [Remix Jam 2025](https://remix.run/blog/remix-jam-2025-recap), and while the first version is targeted for early 2026, the goals are already clear. Remix 3 breaks away from React entirely and rebuilds around web standards.
15
15
16
16
It's a big step. The framework now runs directly on the Fetch API (using standard `Request` and `Response` objects), instead of Node's proprietary `req` and `res` system. This means it can run on any JavaScript runtime; Node, Deno, or Bun, without adapters. It still supports the same patterns developers liked in Remix 2, but without depending on React's lifecycle or its virtual DOM. The team calls this a move toward being "closer to the web itself."
17
17
@@ -33,7 +33,7 @@ The team described six principles that define Remix 3's direction:
33
33
2. Build on web APIs. Use standards like Fetch, Request, Response, and FormData directly. This means a Remix 3 app written for Node can also run on Deno or other JavaScript runtimes without code changes.
34
34
3. Religious about runtime. Avoid build-time "magic." Features should work at runtime, without a custom bundler or code generator. You can still use TypeScript or JSX, but what you write is close to what actually runs.
35
35
4. Avoid heavy dependencies. Remix 3 aims to depend on as little third-party code as possible. Instead of relying on frameworks like React or Express, it implements small, focused modules that the team can control and evolve.
36
-
5. Demand composition. Every piece of Remix 3 is built to work on its own. The router, server utilities, and data parsers can each be used separately or as part of the full framework.
36
+
5. Demand composition. Every piece of Remix 3 is built to work on its own. The router, server utilities, and data parsers can each be used separately or as part of the full framework. This modular philosophy is similar to [TanStack](https://tanstack.com/), where each tool is independently useful but works well together.
37
37
6. Distribute as one. Even though it's modular inside, Remix 3 will ship as a single package. Developers won't need to assemble ten different pieces; the framework will present a unified API.
38
38
39
39
Together, these principles explain why Remix 3 looks so different. The team wants a system that's modular and flexible internally, but simple and predictable on the surface.
@@ -42,7 +42,7 @@ Together, these principles explain why Remix 3 looks so different. The team want
42
42
43
43
Remix 3's architecture centers on the Fetch API. Every incoming request, whether from a browser, a test, or an edge worker, is a standard `Request` object. Every response the framework sends is a `Response` object.
44
44
45
-
At the heart of the system is a new router called `@remix-run/fetch-router`. It's type-safe, explicit, and doesn't depend on file naming conventions. You define routes in code, often in a `routes.ts` file, where each route has a name and a pattern. For example:
45
+
At the heart of the system is a new router called `@remix-run/fetch-router`. It's type-safe, explicit, and doesn't depend on file naming conventions. You define routes in code, often in a `routes.ts` file, where each route has a name and a path. For example:
46
46
47
47
```ts
48
48
export const routes = route({
@@ -53,15 +53,15 @@ export const routes = route({
53
53
});
54
54
```
55
55
56
-
From there, Remix can infer types and generate helpers like `routes.books.show.href({ slug: "gatsby" })`. This keeps links type-safe and prevents mistakes. It also lets the router generate correct URLs for any environment, whether the app runs on Node or Cloudflare Workers.
56
+
From there, Remix can infer types and generate helpers like `routes.books.show.href({ slug: "gatsby" })`. This keeps links type-safe and prevents mistakes. It also lets the router generate correct URLs for any environment.
57
57
58
58
### The new rendering model
59
59
60
-
The biggest change is that Remix 3 no longer uses React. You still write JSX, but it's handled by a small custom runtime built for Remix itself. There's no virtual DOM. When something changes, you update state directly and call `this.update()` to refresh that part of the UI. Events use the browser's native event system instead of React's synthetic one.
60
+
The biggest change is that Remix 3 no longer uses React. You still write JSX, but it's handled by a custom component model built specifically for Remix. There's no virtual DOM. When something changes, you update state directly and call `this.update()` to refresh that part of the UI. Events use the browser's native event system instead of React's synthetic one.
61
61
62
62
This makes the rendering model closer to plain JavaScript. Developers can see exactly what's happening without guessing at hidden framework behavior. The trade-off is that you need to be more deliberate about updates, there's no `useState` hook to trigger automatic re-renders. But it also means fewer performance surprises and much less overhead.
63
63
64
-
To handle partial updates, Remix 3 introduces a feature called Frames. A Frame is a section of the page that can load and update independently. When a Frame refreshes, the server sends back a small HTML fragment, and Remix patches it into the DOM. This allows streaming updates without extra JavaScript or JSON APIs.
64
+
To handle partial updates, Remix 3 introduces a feature called Frames. A Frame is a section of the page that can load and update independently. When a Frame refreshes, the server sends back a small HTML fragment, and Remix patches it into the DOM. This allows streaming updates without extra JavaScript or JSON APIs. This approach is similar to [HTMX](https://htmx.org/), where the server sends HTML instead of JSON, keeping the logic server-side while maintaining interactivity.
65
65
66
66
For example, a comments section could live inside a Frame. When a user submits a new comment, the server renders updated HTML for that frame and sends it down. The rest of the page stays untouched. It feels like client-side interactivity, but it's still server-driven and progressively enhanced.
67
67
@@ -88,7 +88,9 @@ export const handlers = {
88
88
};
89
89
```
90
90
91
-
In this setup, the `GET` handler runs on the server and renders HTML for the initial page. The `POST` handler processes a submitted `<form>`, updates data, and redirects. Remix then re-runs the necessary loaders to refresh the UI. If JavaScript is disabled, the browser still handles the POST and redirect normally, since everything uses standard HTML forms.
91
+
In this setup, the `GET` handler runs on the server and renders HTML for the initial page. The `POST` handler processes a submitted `<form>`, updates data, and redirects. Remix then re-runs the necessary loaders to refresh the UI.
92
+
93
+
This is a key advantage: Remix runs JavaScript on the server but leverages existing browser capabilities on the client side. This makes apps more accessible to parsers, devices with limited JavaScript support, and browsers with JavaScript disabled. The browser handles POST and redirect using standard HTML forms, which works even without JavaScript.
92
94
93
95
This pattern keeps the app predictable. Data always comes from one place, the loader for that route, and every action leads to a clear revalidation path. No client-side fetching hooks or state libraries are needed.
94
96
@@ -102,15 +104,15 @@ This approach prevents a single broken component from blanking the entire page (
102
104
103
105
### TypeScript and developer experience
104
106
105
-
Remix 3 is written in TypeScript from the start, so every route, loader, and action is strongly typed. Route parameters and return types are inferred automatically. For example, if `routes.books.show` has a `:slug` parameter, TypeScript will know that `params.slug` is a string inside its handlers.
107
+
Remix 3 is written in TypeScript from the start, so every route, loader, and action is strongly typed. Route parameters and return types are inferred automatically. For example, if `routes.books.show` has a `:slug` parameter, TypeScript will know that `params.slug` is a string inside its handlers. You can pair this with schema validation libraries like [Zod](https://zod.dev/) to validate form data and API inputs at runtime.
106
108
107
109
Because Remix avoids code generation, you don't need a separate typegen step. The framework infers everything from the code you already write. The same runtime-first philosophy also means you can run your app directly in `ts-node` during development, without waiting for a full build.
108
110
109
-
The development workflow is simpler, too. The preview demos show a single `remix dev` command that starts a local server, watches files, and reloads automatically, no webpack config or complex bundler setup required.
111
+
The development workflow is simpler, too. The [preview demos](https://remix.run/blog/remix-jam-2025-recap) show a single `remix dev` command that starts a local server, watches files, and reloads automatically, no webpack config or complex bundler setup required. While Remix 3 is still in preview, you can follow the [official blog](https://remix.run/blog) and [GitHub repository](https://github.com/remix-run/remix) for early access and updates.
110
112
111
113
### Deployment and environment support
112
114
113
-
Remix 3's platform independence is one of its biggest selling points. Since it's built on the Fetch API, the same app can run on Node, Deno, Bun, or Cloudflare Workers with almost no changes.
115
+
Remix 3's platform independence is one of its biggest selling points. Since it's built on the Fetch API, the same app can run on Node, Deno, or Bun with almost no changes.
114
116
115
117
The router handles incoming requests as `Request` objects and produces `Response` objects, so deployment often comes down to a few lines:
116
118
@@ -121,13 +123,13 @@ import { router } from "./router";
121
123
export default createRequestListener({ router });
122
124
```
123
125
124
-
That pattern works in Node, Vercel, Netlify, or Fly.io. On Cloudflare, it's even simpler, just export `{ fetch: createFetchHandler(router) }`. Because the framework doesn't rely on Node-specific APIs, there's nothing to rewrite when switching platforms.
126
+
That pattern works in Node, Vercel, Netlify, Fly.io, or on edge workers. Because the framework doesn't rely on Node-specific APIs, there's nothing to rewrite when switching platforms.
125
127
126
128
This also makes Remix 3 easier to scale. You can deploy it as serverless functions, edge workers, or a long-running Node process depending on your needs. The framework doesn't force a specific host or vendor. That independence is deliberate; the team wants Remix 3 apps to run anywhere, without lock-in.
127
129
128
130
### Trade-offs and what to expect
129
131
130
-
Rebuilding a framework from scratch isn't free. Dropping React means losing direct access to its huge ecosystem. Libraries like Material UI or React Query won't plug in directly. Developers will either use plain web components, small JS libraries, or future Remix-specific packages.
132
+
Rebuilding a framework from scratch comes with trade-offs. Dropping React means losing direct access to its huge ecosystem. Libraries like Material UI or React Query won't plug in directly. Developers will either use plain web components, small JS libraries, or future Remix-specific packages.
131
133
132
134
There's also a learning curve. Without React's hooks or automatic rendering, you'll manage updates yourself. That's simpler in concept but different in habit. It's a shift from "declare and forget" to "update when needed."
0 commit comments