
2026/04/08 15:01
Railway のフロントエンドを Next.js から切り離し、ビルド時間を「10 分以上」から「2 分未満」に短縮しました。
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
Railwayは、Next.jsからVite + TanStack Startスタックへ、本番フロントエンド(ダッシュボード、キャンバス、およびrailway.com)を完全に移行し、ダウンタイムゼロで実現しました。移行は2回のプルリクエストだけで完了しました:PR 1では
、next/image、next/headなどすべてのNext.js固有APIを削除し、PR 2ではフレームワークを切り替え約200個のルートを移動しました。ビルド時間は10分以上から2分未満に短縮され、ホットモジュールリプレースメント(HMR)が即時化しました。TanStack Startは型安全なルーティング、第一級のパスレスレイアウト、および開発者中心モデルを提供し、Railwayがレンダリングパターンをより厳密に制御できるようになりました。next/router
Railwayは現在、SSR(サーバー側レンダリング)を必要なページ(マーケティングページ、変更ログ、採用情報)のみで使用しています。残りのサイトは完全にクライアント側で動作します。
はNitroに置き換えられ、500件以上のリダイレクト、安全ヘッダー、およびキャッシュルールを1つの設定ファイルに統合しました。また、Nodeポリフィルはブラウザネイティブ代替品へと差し替えました。移行によってビルトイン画像最適化が失われましたが、これは現在next.config.jsタグとFastlyエッジ最適化で処理され、next‑seoやnext‑sitemapなどのエコシステムツールは社内対応に置き換えられています。<img>
フレームワークを変更してもRailwayのデプロイワークフローは変わりません:PRごとにプレビュー展開、ヘルスチェック、およびダウンタイムゼロでのリリースが行われます。Fastlyエッジキャッシュはほぼすべてのトラフィックを直接エッジから提供し、Viteの不変資産モデルはキャッシュフレンドリーなチャンクを保証するため、変更されたモジュールのみが再ダウンロードされます。この決定は、より高速なイテレーションサイクル、クライアントファーストの明確なアーキテクチャ、およびレンダリングパターンへのより良い制御を求める必要性から導かれました。結果として、チームは既存のデプロイメントパイプラインを維持しながら、著しい速度向上とルーティング制御の強化を実現できることが示されています。
本文
目次
- Next.js は当初うまくいったが、やがてそうではなくなった。
- TanStack Start と Vite を選んだ理由
- 2つの PR でダウンタイムゼロを実現
- 放棄したもの
- Railway のフロントエンドは Railway 上で動く
- なぜ今なのか
1. Next.js は当初うまくいったが、やがてそうではなくなった。
Next.js は railway.com をゼロから数百万ユーザーを毎月サービスする本番アプリへと育てました。素晴らしいフレームワークですが、私たちのプロダクトにはもはや最適とは言えませんでした。
- フロントエンドビルドが 10 分を超えるまでに時間がかかり、Next.js のみで 6 分、残りの 4 分は「ページ最適化の確定」に費やされていました。
- 複数回/日頻繁にリリースするチームにとって、このビルド時間は大きなコストです。
- Railway のアプリはほぼクライアント側で動作します:ダッシュボードはリッチで状態を持ち、キャンバスは WebSocket でリアルタイムに更新されます。
- Next.js のサーバー優先のプリミティブはほとんど使われず、Pages Router 上に独自抽象化を構築していました(レイアウトやルーティングに関する要件がフレームワークで満たせなかったため)。
- Pages Router を残したまま共有レイアウトをハックし、すべてのレイアウトパターンはボルトオンの回避策になっていました。
- App Router はいくつかの問題を解決できましたが、サーバー優先に偏り過ぎるため、私たちのプロダクトには合わないと判断しました。
2. TanStack Start と Vite を選んだ理由
実際に構築している形に合わせたい――明示的でクライアントファースト、そして高速なイテレーションを可能にするスタックが欲しかったのです。さらに、作業自体も楽しく感じました。以下のポイントが決め手になりました。
- 型安全なルーティング ― ルートパラメータと検索パラメータは推論され、全ルートツリーでオートコンプリートが機能します。ファイルシステムから自動生成されます。
- 一級レイアウト ― パスレスレイアウトルートが以前のハックを置き換え、構成可能で予測可能な実装に変わります。
- 高速開発サイクル ― 即時 HMR とほぼゼロ起動時間。コード変更と結果確認のフィードバックループが実質消滅します。
- SSR が必要な場面だけ ― マーケティングページ、更新履歴、採用情報は SSR を利用し、それ以外は純粋クライアント側でレンダリング。サーバー描画を強制せずに済みます。
- 明示的モデル ― TanStack はフレームワークのマジックに依存せず、内部構造をコントロールしやすくします。
休日中に数人で TanStack Start を試した結果、全員が「これで作業するのが楽しい」と合意。Railway のダッシュボードというプロダクトには、ベンチマーク以上に重要な点です。
3. 2つの PR でダウンタイムゼロを実現
選択した後は速やかに作業へ。マージ前にスカッシュして数百コミットを行いました。
200+ ルートを持つ本番フロントエンドを移行する場合、通常は並行稼働と段階的切替で何ヶ月も要します。しかし締め切りが迫っていたため、2つの PR で完結しました。
PR 1 – Next.js 固有部分の除去
・next/image
・next/head
をネイティブブラウザ API やフレームワーク非依存代替に置き換え。next/router- フレームワーク自体には変更を加えず、PR 2 がクリーンな切り替えになるようすべての Next.js への依存を除去。
PR 2 – フレームワークの入れ替え
- 200+ ルートを系統的に移行:ページファイルからルーティング以外を個別 React コンポーネントへ分離し、元のページツリーからすべてのルートを生成。
- Nitro をサーバー層として追加し、
を Nitro 設定に置き換え(500+ リダイレクト・セキュリティヘッダー・キャッシュルールを一元化)。next.config.js - Next.js がポリフィルしていた Node.js API(Buffer, url.parse など)をブラウザネイティブ代替へ置き換え、コードをクリーンに。
日曜の早朝にマージ。チームは Discord のライブワーグループで即座にテストし、同日に修正がデプロイされました ― ダウンタイムゼロです。
4. 放棄したもの
- 組み込み画像最適化 ―
をnext/image
タグと Fastly エッジ最適化に置き換え。<img> - エコシステムの一部 ―
,next-seo
などを小規模な社内実装へ差し替え、依存関係を削減。next-sitemap - 成熟度 ― TanStack Start は新しいため、まだ粗い部分がありますが、方向性は正しく、メンテナーの応答も良好。Vite と TanStack のスポンサーであることも安心材料です。
5. Railway のフロントエンドは Railway 上で動く
本番フロントエンドをユーザーと同じ方法で運用しています:PR 毎にプレビューデプロイ、ヘルスチェック、ダウンタイムゼロのローリングリリース。ビルドシステムとフレームワーク全体を入れ替えてもインフラは触らず、コードを書いてプッシュすれば Railway が残りを処理します。
- Fastly はほぼすべてのトラフィックをエッジで直接配信。
- マーケティングページはキャッシュ済み;動的ページは必要に応じて ISR を利用。
- フロントエンドサーバーはほとんどアイドル状態。
- Vite のアセットモデルが特に有効:各モジュールが内容ハッシュ付きチャンクとして分離されるため、請求変更だけを配信すれば他のユーザーは数キロバイトだけダウンロード。
フロントエンドは高速ビルド、イミュータブルでキャッシュフレンドリーなアセット、そしてロールアウト・プレビュー・ルーティングを追加作業なしに処理できるインフラでデプロイされるべきです。フレームワークはイテレーション速度を最適化し、インフラはその結果をユーザーへ見えない形で届けます。
6. なぜ今なのか
フロントエンドのイテレーションスピードがこれまで以上に重要になっています。
- ビルド時間が 10 分超から 2 分以内に短縮。
- 開発サーバーは即時起動。
- ルート変更は境界で型チェックされる。
- レイアウトはワークアラウンドなしで組み合わせ可能。
コードを書いてユーザーへ届けるまでのギャップを埋めることが私たちの課題です。Vite + TanStack はフロントエンド変更をほぼ即時に配信できる環境を提供し、我々が目指す未来を実現します。