PESPAとは?SPA・MPAとの違いとRemix後継(React Router v8)での実装を解説【2026年8月版】
PESPA(Progressively Enhanced Single Page Apps)は、JavaScriptが動かなくても成立する土台の上に、SPAの操作感を後から重ねるWebアプリケーションの設計方針です。同じ綴りのオフィス家具ブランドやスクーターとは無関係の、Webアーキテクチャの用語として説明します。この設計を丸ごと提供した実装先としてよく紹介されてきたRemixは、その後2度動きました。Remix v2はReact Router v7へ引き継がれ、remix.runというドメインが指す製品はReactに依存しないRemix 3へ入れ替わっています。概念の定義と、2026年8月時点でどのフレームワークを触ればPESPAになるのかを、公式ドキュメントとnpmレジストリの実データで確認していきます。
まとめ
PESPAはRemixの共同創業者を務めたKent C. Doddsが「The Web’s Next Transition」で整理した呼び名で、「機能することが基準線であり、JavaScriptは機能を有効化するのではなく強化するために使う」を第一要件とします。MPAのシンプルな考え方を保ったままSPAの体験を得る、という位置づけです。混同されやすいPEMPA(Progressively Enhanced Multi-Page Apps)はPESPAの前段階で、統合された相手ではなく、むしろPESPAが解消した課題(UIコードの手動二重化)の発生源にあたります。
実装先は動きました。Remix v2の次のメジャーバージョンはReact Router v7であると公式が明言しており、2026年6月17日にはReact Router v8.0.0が出ています。一方でremix.runが指すRemixは3系のベータに切り替わり、こちらはReactに依存しない別系統です。Remixの系譜を直接引き継ぐ実装先はReact Router v8のみで、Remix 3は名前が同じだけの新しい枠組みとして分けて評価すべきです。以降で定義・4分類の違い・コード上の現れ方・移行判断の順に見ていきます。
PESPAの定義と提唱者が挙げた5つの要件
PESPAという略語は、Remixの共同創業者を務めたKent C. Doddsが「The Web’s Next Transition」で提示したものです。Epic Web Dev版の構造化データでは初出が2022年10月4日、最終更新が2024年3月27日と記録されています。
原典が列挙するPESPAの要件
同記事はPESPAの特徴として次の5点を挙げています。訳ではなく原文の要点をそのまま示します。
- Functional is the baseline - JS used to enhance not enable(動作することが基準線。JavaScriptは有効化ではなく強化に使う)
- Lazy loading + intelligent pre-fetching (more than just JS code)(遅延読み込みと先読み。対象はJSコードに限らない)
- Pushes code to the server(コードをサーバー側へ寄せる)
- No manual duplication of UI code (as in PEMPAs)(PEMPAで起きるUIコードの手動二重化がない)
- Transparent browser emulation (#useThePlatform)(ブラウザの挙動を透過的に再現する)
ここで注意したいのは、「まず最小限のHTMLとCSSを返し、あとからJavaScriptを足す」という説明はPESPA固有の定義ではない点です。1990年代から語られてきたプログレッシブエンハンスメント一般の説明であり、上の5点のうち1番目に部分的に対応するだけです。PESPAを名乗る条件は、残る4点、とりわけ「UIコードを二重に書かない」と「ブラウザの挙動を透過的に再現する」を満たすことにあります。
JSは強化のみという第一要件が課す制約
「JS used to enhance not enable」は、JavaScriptの読み込みが終わる前や失敗したときでも、フォーム送信とページ遷移が成立することを求めます。スクリプトの取得失敗、拡張機能によるブロック、CDNの地域的な不通といった条件下でも申込みフォームが送れるかどうかが分かれ目です。
この基準線を満たすには、フォームがHTMLのform要素としてサーバーへPOSTでき、サーバー側にその受け口が存在しなければなりません。React Routerであれば、ルートモジュールにactionをエクスポートした時点でその受け口ができます。逆に、送信処理をクライアント側の状態管理ライブラリにだけ持たせた実装は、見た目が同じでもPESPAの条件を外します。ここが、単に「SSRしているSPA」とPESPAを分ける実質的な線引きです。
MPA・PEMPA・SPA・PESPAの違い
4つの呼び名は歴史的な順番で並んでおり、それぞれ「UIを描くコードがどこにあるか」と「JavaScriptが無い状態で何が起きるか」で区別できます。
4アーキテクチャの対応表
| 種別 | UIを描くコードの位置 | JavaScript無効時 | UIコードの重複 | 代表例 |
|---|---|---|---|---|
| MPA | サーバーのみ | 全機能が動作 | なし | PHP、Rails |
| PEMPA | サーバー+クライアント | 基本機能は動作 | 手動で二重化 | jQuery+AJAX、htmx |
| SPA | クライアントのみ | 何も表示されない | なし(クライアント側だけに存在) | React+REST |
| PESPA | 共通コードを両側で実行 | 基本機能は動作 | なし | React Router、SvelteKit |
MPAとSPAは「UIコードが片側にしかない」点では同じで、置き場所が正反対なだけです。PEMPAとPESPAはどちらもその中間を狙いますが、前者は同じ画面を2回書く負債を抱え、後者は1つのコードを両側で走らせて負債を消します。
新規に選ぶ場合の目安は明快です。検索流入が事業に直結する公開ページ、初回表示までの時間が離脱率に響く画面は、サーバー側で完成したHTMLを返せる構成(MPAかPESPA)を前提にします。社内向け管理画面のようにログイン後しか使われず、ブラウザとネットワーク環境を統制できる領域は、SPAで割り切っても実害が出ません。レンダリング方式そのものの整理はレンダリングとは?ブラウザ描画の仕組みとCSR/SSR/SSGの違い・選定基準を解説で扱っています。
PEMPAはPESPAが解消した前段階
日本語の解説で頻繁に見かける誤りが、「フレームワークがMPAとPEMPAを統合してPESPAになった」という説明です。原典の記述はその逆で、PESPAの要件には「No manual duplication of UI code (as in PEMPAs)」と明記されています。PEMPAは参照先ではなく、避けるべき負債の例として名指しされているのです。
PEMPAが指すのは、サーバーでHTMLを組み立てる既存のMPAに、部分更新のためのJavaScriptを後付けした形です。サーバー側テンプレートで書いた行の描画処理を、AJAXで追加する行のためにクライアント側でもう一度書く。テンプレート言語とJavaScriptという別々の言語で同じ表示ロジックが二重化するため、片方の修正漏れがそのまま表示差分として現れます。現代的なPEMPAの実装としてはhtmxが該当し、その具体的な書き方はhtmxの使い方:hx-属性の実装手順からFastAPI連携まで解説【2026年版】にまとめています。
SPAの課題とPESPAが返した答え
SPAで実務上つまずくのは、初期表示の遅さそのものよりも、ブラウザが本来もっていた機能を自前で作り直す作業量です。読み込み中の表示、送信の二重実行防止、送信後のデータ再取得、進む・戻るの履歴管理、スクロール位置の復元は、MPAではブラウザが無償で提供していました。SPAではこれらがすべてアプリケーション側の実装項目に変わります。
PESPAの「Transparent browser emulation」は、この作り直しをフレームワーク側が肩代わりする、という宣言です。React Routerでは、遷移中の状態はuseNavigation(公式は「render pending UI (like a global spinner) or read FormData from a form navigation」と説明)、画面遷移をともなわない部分更新はuseFetcherが受け持ちます。開発者が書くのはHTMLのフォームとリンクで、それをフレームワークが横取りしてクライアント側遷移に差し替える。同じコードのままJavaScriptの有無で挙動が切り替わるため、SPAの体験とMPAの堅牢さが二者択一でなくなります。
PESPA要件のコード上の対応箇所
抽象論だけでは判別しにくいので、React Routerのフレームワークモードを例に、PESPAの要件がコード上のどの部分に対応するかを示します。
actionとFormが担う基準線
React Router公式ドキュメントが示すサーバーアクションの最小形は次のとおりです。
// route('/projects/:projectId', './project.tsx')
import type { Route } from "./+types/project";
import { Form } from "react-router";
import { fakeDb } from "../db";
export async function action({ request }: Route.ActionArgs) {
let formData = await request.formData();
let title = formData.get("title");
let project = await fakeDb.updateProject({ title });
return project;
}
export default function Project({ actionData }: Route.ComponentProps) {
return (
<div>
<h1>Project</h1>
<Form method="post">
<input type="text" name="title" />
<button type="submit">Submit</button>
</Form>
{actionData ? <p>{actionData.title} updated</p> : null}
</div>
);
}
着目すべきはactionが受け取るのがrequestであり、そこからformData()を読んでいる点です。これはブラウザがHTMLフォームを素で送信したときのリクエスト形式そのままで、専用のJSON APIを別に用意していません。Formコンポーネントは、JavaScriptが動いていれば送信を横取りして画面遷移なしで処理し、動いていなければ通常のform要素としてPOSTします。同じ受け口が両方を処理する構造そのものが、「JSは強化にのみ使う」という第一要件の保証になっています。loaderとactionの書き分けはReact Routerのaction・loaderの使い方|clientAction/clientLoaderの違いとv8対応にまとめました。
ミューテーション後の自動再検証
公式ドキュメントはaction完了時の挙動を「all loader data on the page is revalidated to keep your UI in sync with the data without writing any code to do it」と説明しています。更新が終わったら、その画面が使っているすべてのloaderのデータを取り直す、という意味です。
SPAでは、投稿を1件追加したあとに一覧のキャッシュを手で無効化する処理を書きます。書き忘れれば画面と実データがずれ、追加したはずの行が出てこない不具合になります。MPAではフォーム送信後にページ全体が再読み込みされるため、この種のずれは構造上発生しませんでした。PESPAが「ブラウザの挙動を透過的に再現する」と言うとき、この再検証は最もわかりやすい実例です。キャッシュ無効化のコードを書かない、という選択を設計として引き受けている点が、単なるSSR対応との差になります。
ssr:false設定によるPESPA要件の欠落
同じフレームワークでも、設定ひとつでPESPAではなくなります。React Routerでシングルページアプリとして動かす設定は次の1行です。
// react-router.config.ts
import { type Config } from "@react-router/dev/config";
export default {
ssr: false,
} satisfies Config;
公式ドキュメントはこのモードの制約として、ルートルート以外にloaderを置けないこと(事前レンダリングする場合を除く)、ルートルートのloaderはビルド時に一度だけ走ること、実行時のデータ取得と更新はclientLoaderとclientActionで行うことを挙げています。サーバー側にリクエストを処理する層が存在しないため、JavaScriptが動かない環境ではフォーム送信そのものが成立しません。
つまりssr: falseは「PESPAの設定項目」ではなく「PESPAをやめる設定」です。利用環境を統制できる社内管理画面では合理的な選択ですが、その判断をした時点で本記事の設計思想は適用対象から外れます。この切り分けの具体的な条件はRemix SPAモードとは?ssr:falseの設定と制約、React Router移行の判断で整理しています。
2026年8月時点でPESPAを実装する先
2023年に公開された日本語のPESPA解説は、実装先としてRemixを挙げています。その前提はもう最短路ではありません。Remixという名前が指すものが変わったためです。
Remix v2からReact Router v7・v8への系譜
React Router公式の移行ガイドは「React Router v7 is the next major version of Remix after v2」と明記しています。Remixが消えたのではなく、Remix v2の後継としてReact Router v7が出た、という関係です。旧Remixのドキュメントはv2.remix.run/docs/へ移され、そこには「Just getting started with Remix? The latest version of Remix is now React Router v7」という注意書きが置かれ、新規に始める読者はReact Routerのドキュメントへ誘導されます。
移行手順は9ステップで公開されており、公式は「Remix v2のfuture flagsをすべて有効にしてあれば、v2からv7への移行は主に依存関係の更新で済む」と述べています。ステップ2から8についても、その大部分はコミュニティ製のcodemodで自動更新できると案内されています。移行コストの実態は、future flagsをどれだけ放置してきたかでほぼ決まる、と考えて差し支えありません。
React Router v8の必須要件と破壊的変更
そのReact Routerも2026年6月17日にv8.0.0へ進みました。CHANGELOGは、Open Governance移行にともない年1回のメジャーリリース方針を採ったこと、Node 20のEOL時期に合わせて6月を選んだこと、次のv9は2027年5月頃を想定していることを記しています。
| 項目 | v8.0.0の要件・変更 |
|---|---|
| 公開日 | 2026年6月17日 |
| Node | 22.22.0以上 |
| React | 19.2.7以上 |
| Vite | 7以上 |
| モジュール形式 | ESM専用 |
| 削除 | react-router-dom、meta の data、Cloudflare dev proxy |
| 既定化 | v8_middleware、v8_viteEnvironmentApi ほか |
実務で効くのはNodeとReactの下限です。React 19.2.7以上という条件は、React 18で止まっているプロジェクトにとってReact本体の移行が先行タスクになることを意味します。react-router-domの削除も見落としやすい。v7の時点でreact-routerとreact-router/domへインポートを書き換えていなければ、v8で一斉にビルドが通らなくなります。なお2026年8月時点でnpmのlatestは8.3.0(2026年7月22日公開)、v7系も7.18.2(2026年7月28日公開)が出ており、v7が即座に切られたわけではありません。
Remix 3のReact非依存構成
一方、remix.runにアクセスして表示されるRemixは3系です。公式サイトは「Remix 3 is currently available as a beta release」と明記し、サーバー・ルーター・データ層・UIコンポーネント・テストを1つにまとめたフルスタックフレームワークとして紹介しています。
Reactとの関係はnpmレジストリで確認できます。remixパッケージのnextタグは3.0.0-beta.6(2026年8月14日公開)で、そのdependencies46件はすべて@remix-run/で始まる自前パッケージであり、reactもpreactも含まれていません。UIは@remix-run/uiが担います。つまりRemix 3はReactのメタフレームワークではなく、React資産をそのまま持ち込める移行先でもありません。設計思想の詳細はRemix 3 の新しいコンポーネントライブラリとは何か:Web標準ベースのUIコンポーネント設計を解説で扱っています。なおremixパッケージのlatestタグは依然2.17.5(2026年6月1日公開)で、v2系の利用者が黙ってアップグレードされることはありません。
React Router v8とRemix 3の選定条件
結論を先に置くと、Remix v2からの延長線でPESPAを続けるなら、系譜を直接引き継ぐ実装先はReact Router v8だけです。Remix 3は名前の連続性に反して、UIライブラリからテストまで総取り替えになるため、移行ではなく作り直しに相当します。
ただし「PESPAの要件を満たせるのがReact Routerだけ」という意味ではありません。Next.jsのApp Routerも、Server Actionsをform要素のaction属性に渡す形を採っており、公式ドキュメント(バージョン16.3.1、2026年7月28日更新)はbindについて「works in both Server and Client Components and supports progressive enhancement」と記載しています。Remixからの移行という文脈でなく、ゼロから選ぶのであれば比較対象に入ります。
採用を見送るべき場面もはっきりしています。React 18やNode 20から動かせない事情がある場合、v8は要件を満たせないのでv7系(7.18.2)で止めるのが妥当です。Remix 3については、公開が2026年8月14日のbeta.6という新しさを踏まえると、ベータ段階の製品を業務システムの土台に据える判断は時期尚早だと考えます。評価するとしても、既存プロダクトの移行先としてではなく、新規の小規模案件で試す形が現実的です。サーバー側描画の選択肢を広く比較したい場合は、React Server Components(RSC)とは?サーバー・クライアントの違いと使い分けを実装例で解説も検討材料になります。
よくある質問
PESPAは何の略ですか?
Progressively Enhanced Single Page Appsの頭字語です。頭のPEはProgressively Enhanced、つまりプログレッシブエンハンスメントを適用した状態を指します。なお日本語で「pespa」を検索した場合の上位は、同じ綴りのオフィス家具ブランドやスクーターの情報です。技術情報を探すときは「PESPA Remix」「PESPA アーキテクチャ」のように語を足すと目的の資料にたどり着けます。
SPAとMPAはどちらを選ぶべきですか?
二択で考える必要はありません。両者の分岐は「UIを描くコードをサーバーとクライアントのどちらに置くか」でしたが、PESPAは共通コードを両側で実行することでこの分岐自体を解消しています。旧来の二択で悩んでいる場合、選択肢が2つしかないという前提のほうを先に疑ってください。判断基準そのものは本文の「4アーキテクチャの対応表」の直後にまとめています。
React単体でPESPAは実現できますか?
Reactはコンポーネントを描画するライブラリで、ルーティングもサーバー側の受け口も持たないため、単体では条件を満たせません。JavaScriptが無効な状態でフォーム送信を成立させるには、HTMLのform要素がPOSTする先をサーバー側に用意し、同じコードでクライアント側の遷移も処理する層が要ります。React Routerのフレームワークモードのように、ルートごとにloaderとactionを定義できる構成が前提です。
Remixは今も使えますか?
使えますが、名前が指す対象を確認する必要があります。npmのremixパッケージのlatestは2.17.5(2026年6月1日公開)でv2系のままです。v2の後継はReact Router v7以降であり、旧ドキュメントはv2.remix.run/docs/へ移動しています。一方でremix.runが紹介するRemix 3はReactに依存しない別系統のベータで、v2からの連続的な移行先ではありません。
メタフレームワークとPESPAは同じ意味ですか?
違います。メタフレームワークはReactやVueといったUIライブラリの上にルーティングやビルド、サーバー側描画を載せた層を指す一般名詞で、構成を表す言葉です。PESPAはその中で「JavaScriptが無くても動く基盤を保つ」という振る舞いの条件を指します。メタフレームワークであってもSPA専用の構成にすればPESPAの条件を満たしません。実際、React Routerでssr: falseを設定した時点でその状態になります。