UX はフレームワークが作らない ― Next.js 批判に感じた、統一性と体験の責任の置き場所
Published on 2026年9月15日
Next.jsはじめに
Next.js への批判的な記事や投稿を目にする機会が増えた。個々の内容にはここでは触れないが、読んでいて共通して感じる違和感がある。
コードの書き方が揃わないことを、フレームワークの責任にしていないか。 そして、ユーザー体験をフレームワークが担保してくれると思っていないか。
自分は 土台と上物を分ける で、Next.js の肥大化や Vercel への傾倒を懸念として書いた側の人間で、無条件に擁護したいわけではない。「永続する土台としては扱いづらい」という立場は今も変わらない。それでも、批判の論点の置き方には引っかかるものがあった。何が違うのかを、自分の言葉で整理しておきたい。
結論:統一性はフレームワークではなく規約から生まれる
React はコンポーネントをどう分割するか、状態をどこに置くか、props をどう設計するかに何の制約も課さない。書き方が人によって揺れるのは React の性質であって、その上に乗るフレームワークの性質ではない。Next.js を Vite + TanStack Router に変えても、React Router v7 に変えても、この自由度はそのまま残る。
むしろ Next.js は、ファイル規約と RSC の制約がある分、素の React より選択肢を狭めている。app/ 配下の構造、layout.tsx と page.tsx の役割分担、サーバーで取得してクライアントに渡すというデータフローの方向性。これらは「好きに書けない」という不自由さでもあるが、同時に「揃えるための土台がすでにある」ということでもある。
記述の統一性を担保するのは、フレームワークの選定ではなく次のものだ。
| 手段 | 何を揃えるか |
|---|---|
| ESLint のカスタムルール / boundaries 系プラグイン | import の方向、層の侵犯 |
| ディレクトリ規約 | 置き場所、粒度 |
| コンポーネントの分類基準(Atomic Design / FSD など) | 責務の切り方 |
| デザインシステム + Storybook + 型 | UI の仕様そのもの |
| AGENTS.md / CLAUDE.md | AI に対する「うちの流儀」 |
| コードレビュー | 上記をすり抜けたもの |
これは コンポーネント設計が先、JSON ハーネスは最後 で書いたことと同じ構造だ。仕様を閉じ込める場所がなければ、どんな道具を使っても分散する。フレームワークを乗り換えることでこの問題が消えると期待するのは、責任の所在を道具に移しているだけだと思う。
ガードレールを設計するのはエンジニアの仕事であって、フレームワークの仕事ではない。
TanStack を使ったとしても、ガードレールを設計しないチームはやはり揃わない。逆に、規約を設計するチームは Next.js でも揃う。
UX はフレームワークが担保するものではない
もう一つ、Next.js を語るときに「UX」という言葉が雑に使われすぎていると感じる。
Next.js だから、React だから、ユーザー体験が良くなるわけではない。設計が悪ければ、何を使っても体験は悪くなる。
そもそもユーザー体験には階層がある。混ぜて議論すると意味をなさない。
| 階層 | 問い | 決めるもの |
|---|---|---|
| プロダクトとしての UX | ユーザーの課題に対して、どんな成功体験を定義するか | 課題定義、成功の定義 |
| 情報設計・動線 | その定義からどう情報を構造化し、課題解決までの道標をどう整備するか | IA、ナビゲーション、画面遷移 |
| 技術的な UX | 待機時間、スクロールや操作の挙動、描画の安定性 | バックエンドのレスポンス、データ取得の設計、フロントの実装 |
上の二つはフレームワークと無関係だ。課題に対する成功体験を定義せず、動線も整理されていないプロダクトは、Next.js で作ろうが SvelteKit で作ろうが使いにくい。逆にここが設計されていれば、技術的な粗さはある程度まで許容される。
フレームワーク論争で言われる「UX」は、ほぼ三つ目の技術的な UX を指している。ただそれも、フロントのフレームワークだけで決まるものではない。
- バックエンドの API が遅ければ、どれだけストリーミングしても待たされる
- データの取り方が悪ければ、どのフレームワークでもウォーターフォールは起きる
- DB の設計やローカルファーストの導入の有無のほうが、体感に効くことは多い
つまり技術的な UX は、UI からバックエンドまでを 総合的に見た 結果であって、フレームワーク単体の性能や思想で語れるものではない。Next.js の SSR やストリーミングは、その総合の中の一要素にすぎない。効く場面では効くし、ボトルネックが別にあれば何も変わらない。
「Next.js は UX に効かない」も「Next.js なら UX が良い」も、同じ誤りの裏表だと思う。どちらも、フレームワークに体験の責任を負わせている。
境界は「明示的」だから設計が要る
Next.js でよく難しいと言われるのが、Server Components と Client Components の境界だ。"use client" は「そのコンポーネントがクライアントになる」ではなく、「ここから先がクライアントになる」という宣言で、どこに引くかの判断が人によってばらつく。
ただ自分はこれを裏返して読んでいる。
境界が人によって異なる、という議論ができるのは、境界がコードの中に可視化されているからだ。
"use client" はファイルの最上部に境界を書かせる。境界がファイル単位で目に見える。暗黙の境界と、明示的だが設計が要る境界とでは、後者のほうが健全だと思う。
他のフレームワークが境界をどう表現しているかを並べると、Next.js の位置づけがはっきりする。
| フレームワーク | 境界の単位 | 表現方法 |
|---|---|---|
| Next.js(App Router) | コンポーネントツリー | "use client" ディレクティブでツリーの途中に境界を引く |
| React Router v7 / Remix | ルート | loader / action はサーバー、コンポーネントはクライアント。.server.ts / .client.ts の命名 |
| SvelteKit / Nuxt | ファイルの置き場所 | +page.server.ts、server/ ディレクトリ。コンポーネントは両方で描画される前提 |
| Astro | 使う側のテンプレート | デフォルトは完全サーバー。client:load などを付けた箇所だけアイランド化 |
| TanStack Start | 関数 | createServerFn でサーバー処理を関数として切り出す |
Next.js は境界をコンポーネントツリーの中に引く、ほぼ唯一の設計だ。その分「どこで切るか」の判断が細かく発生する。他はルート・ファイル・関数で切るので迷いは小さいが、コンポーネント単位でサーバー描画とクライアント描画を混在させる表現力はない。
「明示的で分かりやすい」という評価と、「粒度が細かいゆえに設計が要る」という指摘は、同じ性質の表裏だ。設計が要るなら、設計すればいい。それがまさにガードレールの話に戻ってくる。
なお、"use client" / "use server" 自体は React の公式仕様であって Next.js 独自ではない。Next.js 固有なのは "use cache" のほうだ。この区別は前の記事でも書いたが、批判の中で混同されていることが多い。
全部入りの価値と代償
自分が Next.js を評価しているのは、フルスタックフレームワークとして全て揃っている ことだ。ルーティング、データ取得、キャッシュ、画像・フォントの最適化、ミドルウェア、サーバー関数、デプロイまで一通りある。
Vite + TanStack Router + TanStack Query + 何かのサーバー、という構成は自由度が高い反面、その組み合わせ自体が「そのチーム独自のフレームワーク」になる。結局それをドキュメント化して揃える作業が発生する。統一性の話に戻れば、揃った規約が最初からあるほうが有利だ。
ここで前提になるのが「基礎的な知識」だ。HTTP キャッシュの意味、サーバーとクライアントで何が違うか、React のレンダリングモデル。この土台がある人にとって、loading.tsx や "use cache" は概念の学習ではなく 「知っている概念がどの名前で置かれているか」の対応表を覚えるだけ で済む。逆に土台がない人は、Next.js でも TanStack でも同じ場所で詰まる。
AI との相性でもこの性質は効く。規約が一つに定まり、公式ドキュメントが整備されているものは、生成コードのばらつきが自然と小さくなる。自由に組んだスタックでは AI に「うちの流儀」を毎回教える必要があり、そこを怠ると書き方は揃わない。
代償ももちろんある。
- 揃っている分だけ、枠から外れるのが難しい
- Vercel 側の設計思想に引きずられる
- 規約が変わると、メジャーアップデートで追従コストが出る
これは「全部入り」の必然的な裏面で、それを嫌うなら自分で組む、嫌わないなら乗る、という選択の話だ。
Vercel ロックインの現在地(以前の自分への訂正)
土台と上物を分ける で、自分は「Next.js を選ぶ = Vercel を選ぶ」という構図への居心地の悪さを書いた。この点は評価を更新しておきたい。
デプロイ面の懸念は、少なくとも実務上はかなり解消されている。
| デプロイ先 | 手段 | 備考 |
|---|---|---|
| Vercel | そのまま | 新機能と同時に対応 |
| Cloudflare Workers | @opennextjs/cloudflare |
OpenNext 経由 |
| AWS / Netlify | OpenNext 系アダプター | 同上 |
| 任意のコンテナ環境 | output: 'standalone' + next start |
Docker に固めればどこでも動く |
差があるとすれば、Vercel は Next.js の新機能と同時に対応するが、OpenNext 系はアダプターが追従する形なので、新しいキャッシュ機構が出た直後は遅れることがある、という点だ。安定版の機能を使う分にはほぼ問題にならない。
つまり Vercel ロックインは 「機能を最速で使えるかどうか」の差であって、「動くかどうか」の差ではない。「Next.js は Vercel 専用」という以前よく見た批判は、今はほぼ当てはまらない。
ただし、前の記事で書いた「上物への依存は 1 箇所に集約し、grep で居場所が分かるようにする」という方針は、デプロイ先の自由度とは別の話なので、そのまま維持する。ホスティングが自由になっても、next/image を 100 箇所に散らせば剥がせなくなることに変わりはない。
自分の選定基準
ここまでを踏まえて、自分がフレームワークを選ぶときの判断軸を置いておく。
| 要件 | 選択 |
|---|---|
| SEO / SSR / ストリーミングが必要なコンテンツ系 | Next.js |
| 管理画面・ダッシュボード・SEO 不要な SPA | Vite + TanStack Router |
| RSC を使いたいが Next.js の厚さが不要 | Waku |
| Web 標準寄りでホスティングを完全に自由にしたい | React Router v7 |
| チームに RSC の境界とキャッシュを説明できる人がいない | Next.js の App Router は選ばない |
Next.js を選ぶ動機は「UX を良くする」ことではなく、SEO・SSR・最適化・デプロイの一体感といった 要件側 にあることが多い。UX は前述のとおり設計で作るもので、フレームワークの選定理由にはならない。要件がなければ選ばないし、あれば自然に候補に上がる。それだけの話で、「よほどの事情がない限り避けるべきもの」とは思っていない。
最後の行が一番大事だ。Next.js は「統一が難しい」のではなく、「統一のために理解しておくべき前提が一つ多い」。その前提を持てる人がいないなら選ばないのは合理的で、それは Next.js の欠陥というより、チームの状況に対する正直な判断だ。
まとめ
フレームワークを変えても、規約を設計しないチームの書き方は揃わない。Next.js ではそれが早く、目立つ形で露呈するだけだ。
境界の設計、キャッシュの難解さ、規約ファイルの多さといった難点は、事実として受け止めるべきだ。ただ、それらを「統一性が保てない」という一つの結論に束ねてフレームワークの責任にするのは、順序が逆だと思う。
統一性は、コンポーネント設計、Lint、ディレクトリ規約、AGENTS.md といったガードレールで作るものだ。それがあれば Next.js でも TanStack でも揃うし、なければどちらでも崩れる。
ユーザー体験も同じだ。成功体験の定義、情報設計、動線、そしてバックエンドまで含めた総合的な技術設計で作るものであって、フレームワークが担保してくれるものではない。設計が悪ければ、Next.js でも React でも体験は悪くなる。
自分が Next.js を「永続する土台」として扱いづらくなっていることと、Next.js だと書き方が揃わないという主張とは、別の話だ。前者は今も感じている。後者には同意しない。その区別をつけておきたくて、この記事を書いた。