世界を動かす技術を、日本語で。

RailwayのフロントエンドをNext.jsから移行しました。ビルド時間が10分以上から2分未満に短縮されました。

概要

RailwayのフロントエンドはNext.jsからVite + TanStack Routerへ全面移行。 移行は2つのPRで無停止で完了、ビルド時間は10分超から2分未満に短縮。 Next.jsのサーバー中心設計がRailwayのクライアント主導開発と合わず、独自実装が増加。 Vite + TanStack Routerは型安全なルーティングや高速な開発体験を提供。 一部機能やエコシステムを手放すも、将来性と開発効率を重視した決断。

Railway フロントエンドのNext.js卒業

  • Railwayの全プロダクションフロントエンド をNext.jsから Vite + TanStack Router へ移行
  • ダッシュボード、Canvas、railway.com など全てのUIが新スタックで稼働
  • 2つのPRで移行を完了、ユーザーへの ダウンタイムはゼロ
  • Next.jsは初期の成長を支えたが、 ビルド時間の長期化設計思想の不一致 で限界
  • ビルド時間が10分超、うちNext.js関連だけで6分を占有
  • 頻繁なデプロイ を行う開発体制にとって、 長いビルドは大きな障害
  • Railwayのアプリは クライアントサイド中心、リアルタイムなUIとWebSocket活用
  • Next.jsの サーバー優先設計 やPages Routerの制約で 独自実装や回避策が増加
  • App Routerも サーバー中心 でRailwayのニーズに合わず、全面的な再設計が必要に

Vite + TanStack Router選定理由

  • 明示的・クライアントファースト ・高速な開発ループに適合
  • 型安全なルーティング、パラメータ推論やオートコンプリートがルート全体で機能
  • パスレスレイアウト で従来のハックを排除し、 予測可能なレイアウト構成 を実現
  • 爆速の開発ループ、HMR即時反映・起動ほぼゼロ秒
  • SSRは必要なページのみ、他は完全クライアントサイド
  • フレームワークの隠蔽よりも制御性重視、内部挙動の把握が容易
  • チーム全員が開発体験を高評価、Railwayのダッシュボードに最適

2つのPRによる無停止移行

  • PR1: Next.js固有のAPI(next/image, next/head, next/router)を全て排除
    • ブラウザ標準APIやフレームワーク非依存な代替手段 へ置換
    • フレームワーク自体は未変更、依存性だけをクリアに
  • PR2: フレームワーク本体のVite + TanStack Routerへの全面切り替え
    • 200以上のルートを移行、ページファイルからロジックをReactコンポーネントへ分離
    • ルートツリーから自動生成
    • Nitroをサーバーレイヤーに導入、リダイレクトやセキュリティヘッダー・キャッシュルールを一元管理
    • Node.js APIのpolyfillも排除、ブラウザ標準APIで統一し コードが簡潔化
  • 日曜朝にマージ、Discordでライブ監視し即日修正対応完全なゼロダウンタイム移行

失ったものと得たもの

  • next/imageのビルトイン画像最適化を放棄、imgタグ+Fastlyのエッジ最適化へ移行
  • next-seoやnext-sitemap等のエコシステムも自作ツールで代替
  • TanStack Startは新しい技術、未成熟な部分もあるが 方向性とメンテナの対応力 を評価
  • ViteとTanStackにスポンサー支援、今後の発展に期待

Railway自身によるRailwayの運用

  • 本番フロントエンドもRailway上で運用
  • PRごとのプレビュー、ヘルスチェック、ゼロダウンタイムロールアウト を実現
  • インフラには一切手を入れず、コード変更のみで完結
  • Fastlyでエッジ配信、マーケティングページはキャッシュ、ダイナミックページはISR
  • Viteのアセットモデル でチャンク単位のキャッシュ制御、変更範囲のみ再配信
  • ユーザーへの配信は数KB単位に最適化

フロントエンド開発の今後

  • ビルド時間は10分超から2分未満に短縮
  • 開発サーバー即時起動、ルート変更も型安全にチェック
  • レイアウトもワークアラウンド不要で柔軟に構成
  • 「書いたコードが即ユーザーに届く」体験を最重視
  • Vite + TanStack Routerでほぼリアルタイムなフロントエンド開発 を実現
  • この体験を自社・ユーザー双方に提供することが目標

Hackerたちの意見

私たちも似たような移行を経験したよ。Next.jsのランディングページと別のTanStack RouterのSPAを持ってたんだけど、両方を一つのVite + TanStack Startアプリに統合したんだ。ビルド時間やアーキテクチャのミスマッチも同じような感じで、うちのアプリはクライアントサイドが重視されててリアルタイムの状態管理をしてるから、Next.jsのサーバー優先の前提に戦うのは無駄だった。TanStack Routerの型安全なルーティングとファイルベースのルート生成は素晴らしいよ。

TanStackのことは知らなかったけど、彼らのウェブサイトをちょっと見た感じ、正直あんまり信頼できそうにないな。例えば「TanStack Pacer」なんて、こんなことを提供してるんだよね。import { Debouncer } from '@tanstack/pacer' // クラス const debouncer = new Debouncer(fn, options) debouncer.maybeExecute(args) // デバウンスされた関数を実行 debouncer.cancel() // デバウンスされた関数をキャンセル debouncer.flush() // デバウンスされた関数をフラッシュ なんでデバウンスを実装するのに「フレームワーク」をインストールする必要があるの?これがノードエコシステムが不安定で脆弱な理由なんじゃないの?バニラJSでシンプルなデバウンサーを書けばいいのに…。

今、Next.jsを使ったアプリがあって、ビルドに約7分かかってる。でも、ずっと前からNextをやめたいと思ってたんだ。TanStackはいい感じだし、これで移行する自信がちょっと湧いてきた。

C++開発者として、そこには笑っちゃったよ。うちのコンパイル時間が悪いと思ってたけど。

中規模プロジェクトにTanStack Startを使ってて、結構満足してる。ビルド時間がNextと比べてどうなるかはわからないけど、同じくらいのサイズのRemix(ごめん、React Router v7)アプリはビルドにもっと時間がかかる。TanStackは全体的にいいメンタルモデルを持ってて、キャッシュのバリデーションとかでTanStack Queryともうまく連携する。Remixは期待できたけど、APIルートの登録にすごく手間がかかった。TanStackは特に手間なくサーバー関数を自由に定義できるから、試してみる価値はありそうだし、Claude Codeに移行してビルド時間や使い勝手をテストしてもらうのもいいかもね。

サーバーレンダリングされたHTMLって2026年のウェブにとってそんなに悪いの?それともみんな複雑なアプリを作ってるの?多くの顧客がNext.jsや似たようなものを使いたがるけど、彼らのウェブサイトを見てるとその理由がわからない。ページ内のインタラクションは基本的なものに限られてるのに、メガバイトのJSをダウンロードして実行してる。オフラインモードが必要なプロジェクトなんて見たことないし。もしかしたら、[FRAMEWORK]の開発者を簡単に別の人に替えられるってことなのかも。

ターボパック使ってる?Next 16で利用可能で、ビルド時間が6分から2分に短縮されたよ。

フロントエンドのウェブ開発に真剣に取り組もうとしたのが2回あって、5年くらい間が空いてるんだ。どちらも一番人気のフレームワークから始めたんだけど、プロジェクトを終える前にそのフレームワークが別のものになってた。あんまり状況は変わってないのかな?

最近、NextJSからReact Routerに移行したんだけど、NextJSでは作ったプロジェクトのどれもがデプロイに7〜8分かかってたのが、React Routerにしたら1〜2分に減ったよ。環境変数の扱いにちょっと苦労したけど、変化には大満足で、もう戻る気はないかな。

皮肉なことに、Next.jsをRailwayプラットフォームにデプロイするのはすごく遅いんだ。彼らはコンテナを使ってるから、Vercelでは2分のビルドがRailwayでは12分くらいかかる。VPSでのデプロイは20秒くらいなのに。*これはビルド時間の話だから、デプロイ時間とは違うけどね。

コンテナのせいじゃなくて、過剰なリソースの割り当てやビルドにどれだけのリソースを使ってるかが問題だよね。Vercelがどうやって数秒でビルドを終わらせるのかは分からないけど、まあ、彼らはNextJSの開発者だからね。DollarDeployでもコンテナを使ってビルドしてるけど、毎回4GB/2CPUを割り当ててるから結構速いけど、Vercelほどではないかな。

2分ってまだまだ長すぎるよ。何やってるんだ?これはおかしい。

構造型チェックをする言語なのに、最初からそのことを考慮して作られてないんだよね。

数百万ユーザーのアプリの本番デプロイに2分?全然いいじゃん!どれくらい速いのを期待してるの?

多くのLLMはnext.jsに詳しいし、VercelもLLM向けのツールを使ったエコシステムを積極的に構築してるみたい。だから、みんながLLMを使うときにnextを使うように強く促されると、この問題がさらに悪化するんじゃないかって思うんだ。

VercelのテンプレートからNext.jsプロジェクトを作ると、「THIS IS NOT THE NEXT.JS YOU KNOW」って書かれたAGENTS.mdがもらえるよ。

LLMが登場する前から、クソ重いウェブサイトはあったよね。

彼らのドメインページを試してみたら、10.8MBのデータを使って、DOMが準備できるまでに2秒かかった。ページ全体のレンダリングには17秒もかかって、シフトチェンジが何回もあったよ。結局、Googleのホームページに似たドメイン検索バーをレンダリングするためにね。 https://railway.com/domains

なんてこった。あのページをスクロールするのが実際に遅いんだよね。

ウェブ開発って、本当にクソだな。俺のプロジェクトは全部、jinja/minijinjaでサーバーサイドレンダリングしてて、bootstrap、jQuery、フォームにちょっとSPAっぽい動きを加えるためにhtmxも使ってる。ビルドなしで、ただ静的な<script src=タグだけ。めっちゃ速くて簡単。もう他のは絶対勧めない。

3.57MBの背景PNG、マジで笑える [0] [0] https://railway.com/dots-oxipng.png

このページには簡単にできる最適化がいくつかあるけど、上位のものはフレームワークに関係ないんだよね。ビルド時間が短くなれば、画像やサードパーティの依存関係を簡単に最適化できるかも。誰かが指摘してたけど、そのデータのほぼ半分は最適化されてない画像なんだって。興味がある人のために言うと、Googleの現在のホームページは200KBのペイロードで、約50倍小さいんだよ。

アプリのランディングページをNext.jsからAstro.jsに移行したんだけど、主な理由は静的ページを提供するのにVercelに月20ドルも払ってたから。これって、実際のアプリのPostgresデータベースに払ってるRailwayの4倍、Cloudflareにアプリをホスティングするために払ってる金額の4倍なんだ。移行にはAIを使って、既存のリポジトリを「指示」として使ったから、数日で終わったよ。ちょっとしたアップグレードや改善も含まれてたしね。 [1]: https://www.sqlai.ai/

これ、いいね!

なんでみんな5ドル/月のUbuntu/Debian VPSを借りて、nginxをインストールして終わりにしないの?それで同じサーバーで複数のプロジェクトを動かせるのに。

RailwayはRailsを試してみるべきだね。

JS開発者は新しいキラキラしたフレームワークから離れられないよ。

これを読んでめっちゃ良かった: 「私たちはViteとTanStackの両方を支援しています。なぜなら、彼らの進む方向を信じているからです。」こういう姿勢がもっと見たいな。