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 時代截然不同的模型。

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

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

小夜