Remix 3 Beta:脱离 React,以 Web 标准重写全栈框架

前言

Remix 是 React Router 团队打造的全栈 Web 框架,2022 年被 Shopify 收购后持续演进。熟悉前端演进脉络的开发者大概记得:2025 年 5 月,联合创始人 Michael Jackson 与 Ryan Florence 在官方博客发表《Wake up, Remix!》,宣布 Remix v2 的核心能力已并入 React Router v7,Remix 将「睡醒了」重新出发——不再绑定 React 生态,改以 Web 平台原语从零搭建一套 UI 无关的全栈框架。

2026 年 4 月 30 日,团队正式发布 Remix 3 Beta Preview;据 InfoQ 等后续报道,预览版已推进至 v3.0.0-beta.5,团队计划每周迭代。对仍在 Remix 2 上维护生产应用的团队,官方路线很明确:迁移至 React Router v7;Remix 3 则面向愿意从头实验的新项目。这一分叉,在前端社区引发了不少关于「框架该绑定 React 还是拥抱 Web 标准」的讨论。

从「中间层」到「完整栈」

Remix 1、2 以及同期的 React Router,定位都是「center stack」——框架负责路由与渲染,数据库、UI 组件库、认证等往往要开发者自行拼装。Remix 3 试图回答另一个问题:如果把路由、请求处理、中间件、会话、认证、表单、文件上传、静态资源、数据层、UI 组件、主题、网络与测试全部纳入同一套模型,会是什么样子?

答案是一套以 remix 单包 对外分发、内部由多个可独立使用的小包组成的工具箱。安装 npm install remix 后,可通过子路径按需引用,例如 remix/fetch-router(路由)、remix/auth(认证)、remix/data-table(数据层)、remix/ui(UI 运行时)等。官方强调:对外体验应 cohesive(开箱即用),对内结构应 composable(可替换、可拆离)。

底层放弃 React,改用 Preact Fork

Remix 3 最引人注目的变化,是 安装时不再拉取 react 依赖。前端仍写 JSX,但运行时换成了团队 fork 的 Preact,并在此基础上自建组件模型——状态是普通 JavaScript 变量,变更通过 handle.update() 显式通知渲染;异步逻辑配合标准 AbortController 取消;事件绑定统一走 on 属性;样式与行为通过 mixin 组合到元素上。

官方博客给出的 CopyToClipboard 示例,能直观看出这套 imperative(命令式)风格:

import { type Handle, on } from "remix/ui";
import { Glyph } from "remix/ui/glyph";
import * as btn from "remix/ui/button";

function CopyToClipboard(handle: Handle<{ url: string }>) {
  let state: "idle" | "copied" | "error" = "idle";

  return () => {
    let label =
      state === "idle"
        ? "Copy to clipboard"
        : state === "copied"
          ? "Copied"
          : "Error";

    return (
      <button
        aria-label={label}
        aria-live="polite"
        mix={[
          btn.secondaryStyle,
          on("click", async (_, signal) => {
            try {
              await navigator.clipboard.writeText(handle.props.url);
              if (signal.aborted) return;
            } catch (error) {
              state = "error";
              handle.update();
              return;
            }

            state = "copied";
            handle.update();
            setTimeout(() => {
              if (signal.aborted) return;
              state = "idle";
              handle.update();
            }, 2000);
          }),
        ]}
      >
        {state === "copied" ? (
          <Glyph name="check" />
        ) : (
          <Glyph name="clipboard" />
        )}
      </button>
    );
  };
}

这里没有 Hooks,也没有隐式依赖追踪;读代码时逻辑顺序一目了然。选用 Preact 而非 React,官方在《Wake up, Remix!》中给出的理由是:Shopify 等生产环境已大规模使用 Preact,体量和 API 面足够小,便于 fork 后完全掌控演进节奏,符合「零关键外部依赖」的目标。

全栈统一在 Fetch API 之上

服务端侧,Remix 3 的路由即 Fetch API 路由:控制器返回标准 Web Response,中间件接管请求生命周期,表单提交指向 URL,会话与认证上下文与数据和 UI 共享。在 Node.js 环境,可通过 remix/node-fetch-servernode:http 的请求转换为 Web 标准的 Request/Response 流,与 Cloudflare Workers 等边缘运行时使用同一套抽象。

这种设计让「写服务端」与「写客户端 fetch」在心智模型上高度一致——不再额外维护一套 RPC 或框架专有 loader/action 协议(尽管 Remix 2 的 loader 模式本身也深受 Web 表单启发)。测试也可以直接复用线上同一套路由器,减少 mock 层。

Frames 与 Unbundling:两个新原语

Frames 是 Remix 3 重点推广的 UI 原语:带 src 的服务端渲染片段,客户端可独立加载、导航或刷新,页面其余部分无需整体重绘。官方 bookstore 演示中,购物车以 Frame 形式嵌入商品页,加购后只更新购物车片段。不少观察者将其与 HTMX、Turbo 的局部刷新思路类比——差异在于 Remix 3 把这一模式纳入框架一等公民,并与 Fetch 路由、表单提交打通。

Unbundling(解 bundler 化) 则是另一项架构赌注:运行时而非打包器成为应用的「真相来源」。资源仍由 Remix 编译与服务,但应用模型不依赖大规模预运行时静态分析;import 语句没有特殊语义。团队认为,这不仅减轻人类开发者对工具链的耦合,也让 AI Agent 更容易理解项目结构——路由、控制器、中间件、数据表、表单、Frame 都是边界清晰、可独立描述的模块。

六条设计原则

《Wake up, Remix!》中列出的原则,在 Beta 代码里已有具体体现:

  1. Model-First Development:优化源码、文档与抽象,使其便于 LLM 理解与生成;同时为应用内集成模型预留能力。
  2. Build on Web APIs:全栈共享 Request/Response、fetch、AbortController 等标准接口,减少上下文切换。
  3. Religiously Runtime:API 设计不迁就 bundler/编译器的静态分析能力;测试在不打包的前提下运行(允许 --import loader 处理 TS/JSX)。
  4. Avoid Dependencies:谨慎引入第三方包,完全包裹后逐步替换,目标是零关键依赖。
  5. Demand Composition:抽象应单一职责、可增可删;新功能优先做成独立包。
  6. Distribute Cohesively:学习成本与组合自由度之间取平衡——小包独立可用,对外仍以 remix 单包统一文档与分发。

Remix 2 用户该走哪条路?

这是社区讨论最集中的问题。官方立场没有模糊空间:

  • 现有 Remix 1/2 应用:应迁移至 React Router v7(framework mode)。v7 已于 2025 年 11 月发布,整合了原 Remix 的打包器与服务端运行时,并在 Shopify、GitHub、Linear 等大规模应用中落地;Cloudflare 文档也已明确建议新项目改用 React Router Workers 指南。
  • Remix 3:定位为 全新起点,不是 v2 的就地升级。早期迁移案例多为完整重写,而非改几个 import。

React Router v7 继续走 React 全栈路线(含 RSC 预览支持);Remix 3 则彻底 UI 无关地押注 Web 标准。两条线并行,由团队分别维护,避免了 v2 时代 Remix 与 React Router「人为割裂」的尴尬。

快速体验 Beta

官方声明 Beta 尚未生产就绪,适合实验、原型与反馈。当前创建项目:

npx remix@next new my-remix-app

Beta 预览已包含路由、会话、认证、表单、上传、静态文件、资源分发、数据层、服务端渲染、UI 等核心模块。团队承诺每周发布新功能,sharp edge 需靠社区试用暴露。

社区怎么看

反响颇为两极。支持者认为 Remix 3 是「更接近 Web 本质的全栈方案」——Fetch 路由、Frame 局部刷新、命令式组件,组合起来比堆叠 React + Vite + 若干中间件更直觉;有开发者反馈,框架边界清晰、贴近 Web 标准,对 AI 辅助编码尤其友好。

质疑声同样响亮:Remix 在 major 版本间方向变化过大,v2 用户需整体迁往 React Router,v3 又与 React 生态彻底脱钩;有人质疑「React Router v7 + Vite」已能满足多数需求,Remix 3 的增量价值是否值得再学一套模型。Hacker News、r/reactjs 上的争论,本质上是在问:2026 年的全栈框架,默认还应不应该叫「React 框架」?

小结

Remix 3 Beta 不是一次常规大版本升级,而是一次产品重新定义:React Router 承接 Remix 2 的遗产与 React 生态,Remix 3 则在 Fetch API、Preact fork、Frame、Unbundling 之上,尝试构建一套 UI 无关、运行时优先、依赖极少 的全栈工具箱。它是否能在 Next.js、SolidStart、SvelteKit 之外开辟第三条路,取决于 Beta 阶段社区反馈与后续每周迭代的兑现程度。

若你今年有生产交付压力,React Router v7 是稳妥选择;若你对「 lighter、closer to the web itself 」的开发体验有好奇,不妨用 npx remix@next new 搭个小 demo,亲自感受这套与 React 时代截然不同的模型。

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜