3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Remix 3 は React 依存を脱却し Web 標準へ

3
Posted at

はじめに

Remix 3 は React 専用フレームワークであることをやめ、Web 標準の上で再構築するという発表が2025年10月の Remix Jam 2025でありました。26年1月時点で Remix 3 は開発段階ですが、今後の Remix / React Router がどうなっていくのか情報を整理しておきたいと思います。

image.png

(出典)Remix 公式サイト(2026年1月時点)

Remix の歴史

image.png

(出典)Remix 公式サイト(2026年1月時点)

Remix は React Router と同じチームが開発しています。React Router から派生して、「Web標準の上に構築する(Build on Web APIs)」という考え方の下、フルスタックフレームワークとして登場しました。

React は2016年頃からフロントエンドフレームワークとして広く使われ続けてきた技術です。React の上に様々なエコシステムが構築されています。一方で React に依存している状況が進んでいるとも捉えることができます。Web標準に則ることは開発者にとってポータビリティのあるスキルと経験を積めることになります。

Remix は一度 React Router と合流しましたが、再び独立した形で開発を進めているようです。

react-router-remix-graphic.jpeg

Graphic by Jacob Paris

Remix v2 と v3 の違い

特徴 Remix v2 まで Remix v3 から
UI 依存度 React 専用 UI 非依存(Framework agnostic)
コアロジック React のエコシステムに密結合 純粋な Web Standard APIs に分離
実行環境 Node.js が主役 あらゆる JS ランタイム(Edge, Bun, Deno 等)
AI 親和性 複雑な抽象化が多い モデル(LLM)が理解しやすいシンプルな構造

Remix 3 をコードリーディングし、理解を深める

ここからは生成AIとGitingestを用いて公式リポジトリをコードリーディングし、生成AIと対話しながら理解した内容を抜粋して記載します。間違った理解をしている場合はご指摘を頂けますと嬉しいです。

Remix 3 のWebアプリケーションランタイム、フレームワークのレイヤーは React 依存を脱却して、Web標準(Web APIs)に移行します。React, Vue 等の UI フレームワークは Remix 3 の上に載ることとなります。Remix 自体はルーティング、データ、サーバーに軸足を置くことになります。

設計思想

  • Model-First (AI への最適化): 人間だけでなく LLM(大規模言語モデル)にとっても理解しやすい抽象化とソースコードを目指す。

  • Web API 基盤: 独自 API ではなく、Fetch, Web Streams, Uint8Array, Web Crypto などの標準 API を徹底活用する。

  • Runtime 中心: ビルド時の静的解析に依存せず、ブラウザや多様なランタイム(Node.js, Deno, Bun, Cloudflare Workers)でそのまま動く設計。

  • 脱依存関係 (Avoid Dependencies): 外部ライブラリへの依存を最小限(理想はゼロ)にし、必要な機能は自前で高品質なパッケージを作る。

私は Remix 3 は4つの階層で構成されると理解しました。

Code_Generated_Image.png

Layer 4. アダプター層
React, Vue, Solid などが載ることになります。Remix 3 のルーティングやデータ取得機能を、各 UI フレームワークから利用するためのブリッジとなります。

Layer 3. UI 抽象化層
UI をどう表示し、イベントをどう処理するかを定義します。パッケージとして component, interaction, html-template 等が提供されます。React がなくても「コンポーネント化された Web アプリ」が作れるようになります。

Layer 2. コアフレームワーク層
「Web アプリケーションランタイム」として機能します。ルーティング、HTTP ヘッダー管理、セッション、フォームデータのパースなど、Web アプリの「土台」を提供。ここには React のコードは含まれず、純粋な JavaScript/TypeScript で記述されます。

Layer 1. Web 標準基盤層
特定の UI フレームワークやランタイム(Node.js など)に依存せず、ブラウザでもサーバーでも動く標準的な機能を使います。使用技術は Request, Response, Fetch API, Streams, URLPattern など。

Remix vs React コード比較

Remix 3 単体でも UI コンポーネントは作れますが、UI コンポーネントライブラリとも連携させることができます。Layer 3と 4 を比較すると以下のようになります。

比較項目 Layer 3(UI抽象化層) Layer 4(アダプター層)
主な対象 DOM(ブラウザ) React / Vue / Solid 等
依存関係 特定のフレームワークに依存しない 特定のフレームワークに依存する
開発スタイル Web 標準に近い軽量な記述 フレームワーク特有の記述(JSX、フック等)
存在理由 フレームワークなしでの動作を可能にする 既存エコシステムを利用可能にする

Layer 3. Remix 版カウンターコンポーネント

// handle: このコンポーネントの表示を制御するコントローラー
// setup: コンポーネントが作成(マウント)される時に一度だけ渡される初期値
function Counter(handle: Handle, setup: number) {
  // --- Setup Phase ---
  // この関数スコープは「一生に一度」しか実行されません。
  // そのため、React のように useState を使わなくても、
  // ただの変数 (let) がそのまま「永続的な状態」になります(クロージャ)。
  let count = setup

  // --- Render Function ---
  // この戻り値の関数が、データ更新(handle.update)のたびに実行されます。
  // 引数の props には、親から渡される最新の値が入ります。
  return (props: { label?: string }) => (
    <div>
      {/* 描画時にはクロージャにある count 変数を直接参照します */}
      {props.label || 'Count'}: {count}

      <button
        // Remix 3 独自のイベント登録(ブラウザ標準のaddEventListenerに変換される)
        on={{
          click: () => {
            // 1. 状態を直接更新(ただの JS 変数操作)
            count++
            
            // 2. 明示的に「表示を更新して」とフレームワークに命令
            // これにより、上記の render function が再実行されます。
            handle.update()
          },
        }}
      >
        Increment
      </button>
    </div>
  )
}

Layer 4. React 版カウンターコンポーネント

import { useState } from 'react'

// React では handle や setup 引数ではなく、すべて props (または hooks) で扱います
function Counter({ setup, label }: { setup: number; label?: string }) {
  // Setup phase に相当: useState の初期値として setup を使用
  const [count, setCount] = useState(setup)

  // React では関数全体が "render function" として毎度実行されます
  return (
    <div>
      {label || 'Count'}: {count}
      <button
        // Remix 3 の on={{ click: ... }} ではなく onClick を使用
        onClick={() => {
          // count++ と handle.update() の代わりに state 更新関数を呼ぶ
          setCount((prev) => prev + 1)
        }}
      >
        Increment
      </button>
    </div>
  )
}

主要パッケージ

各パッケージは公式リポジトリから詳細を確認してください。component 以外のパッケージも触れたかったところですが、本稿では割愛します。

パッケージ名 説明
async-context-middleware AsyncLocalStorage にリクエストコンテキストを保存するためのミドルウェア
component JavaScript と DOM プリミティブに基づいた最小限のコンポーネントシステム
compression-middleware HTTP レスポンスを圧縮するためのミドルウェア
cookie JavaScript でクッキーを扱うためのツールキット
fetch-proxy Web Fetch API 向けの HTTP プロキシ
fetch-router Web Fetch API 向けの最小かつ合成可能なルーター
file-storage JavaScript の File オブジェクト向けのキー/バリューストレージ
form-data-middleware リクエストボディから FormData を解析するミドルウェア
form-data-parser ストリーミングファイルアップロードに対応した request.formData() ラッパー
fs Web File API を利用したファイルシステムユーティリティ
headers JavaScript で HTTP ヘッダーを扱うためのツールキット
html-template 自動エスケープ機能を備えた HTML テンプレートタグ
interaction コンポーネントに近い概念でイベントを扱う仕組み
lazy-file JavaScript 向けの遅延・ストリーミング対応ファイル
logger-middleware HTTP リクエスト/レスポンスをログ出力するミドルウェア
method-override-middleware フォームデータから HTTP メソッドを上書きするミドルウェア
mime MIME タイプを扱うためのユーティリティ
multipart-parser あらゆる JavaScript 環境で動作する高速・高効率な multipart ストリームパーサ
node-fetch-server Web Fetch API を用いて Node.js 用サーバーを構築するためのツール
route-pattern 強い型付けで URL のマッチングと生成を行う
session JavaScript 向けのセッション管理
session-middleware クッキーベースのストレージによるセッション管理ミドルウェア
static-middleware ファイルシステムから静的ファイルを配信するミドルウェア
tar-parser あらゆる JavaScript 環境で動作する高速・高効率な tar ストリームパーサ

おわりに

React は10年以上最前線で使われてきたフロントエンドフレームワークであり、その歴史の分だけエコシステムも充実しています。私は今後もそのポジションは早々には変わらないと思います。
しかし、Remix の開発者は React に依存することをやめ、Web標準に根差した Remix は、より多くの開発者が、より長く使えるフレームワークである、と言いたいのだろうと読み取りました。生成AIの時代を見越し、標準に沿っていくことでAIの支援を受けやすくなることも強調しているように思えました。

本記事では Remix 3 のほんの一部しか紹介できませんでした。今後の開発状況を見ながら、続報を記事にしたいと思います。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?