When Next.js stops fitting: lessons from Railway's move to Vite + TanStack
By Arash Latifi
Railway moved its entire production frontend off Next.js to Vite and TanStack Start — builds went from 10+ minutes to under 2. Why they did it, how they did it in two PRs, and what they gave up.
TL;DR — Railway moved its 200+ route production frontend from Next.js to Vite + TanStack Start in two PRs with zero downtime; builds dropped from 10+ minutes to under 2. The root cause was a fully client-side app fighting Next.js's server-first model — not Next.js being bad.
How it started
Railway (the cloud hosting platform) published a detailed postmortem of why their entire production frontend no longer runs on Next.js. Notably, they never trash the framework — they credit it with taking railway.com from zero to an app serving millions of monthly users. But the costs crept up:
- Builds passed 10 minutes. Roughly half of it stuck on "finalizing page optimization." For a team shipping multiple times a day, that's a heavy tax on every iteration.
- Their app is inherently client-side. The dashboard is a rich, stateful interface, the canvas is real-time, Websockets are everywhere. They never used Next.js's server-first primitives and had bolted their own layout/routing abstractions onto the Pages Router.
- They knew App Router would fix some of it — and still didn't adopt it. App Router leans into server-first patterns; their product is intentionally client-driven. Migrating meant rebuilding around a paradigm they don't need.
One thing worth flagging for decision-makers: Railway competes directly with Vercel, and commenters raised it — but the post's stated reasons are technical, and team members in the HN thread confirmed the rivalry wasn't the driver. Build time and architecture mismatch were.
Two PRs, zero downtime
Migrating 200+ routes usually takes months of parallel running. They did it in two pull requests:
- PR 1 removed everything Next.js-specific.
next/image,next/head,next/router— each swapped for a native browser API or a framework-agnostic alternative. This PR changed nothing about the framework; it just zeroed out the dependency so PR 2 could be a clean swap. - PR 2 swapped the framework. Everything non-routing-related was first extracted from page files into plain React components, then all routes were regenerated from the original page tree. Nitro became the server layer and
next.config.jswas replaced with Nitro config — 500+ redirects, security headers, and caching rules consolidated in one place. Node APIs Next.js had polyfilled (Buffer,url.parse) were replaced with browser-native alternatives.
Merged on an early Sunday morning, dogfooded via a Discord war room, fixes landed same day. No downtime.
What they gained, what they gave up
| Aspect | Before (Next.js) | After (Vite + TanStack) |
| --- | --- | --- |
| Production build time | 10+ minutes | under 2 minutes |
| Routing | Pages Router with layout hacks | type-safe routing + pathless layout routes |
| Image serving | next/image | <img> tags + Fastly image optimization at the edge |
| Asset caching | large bundles | per-module content-hashed chunks |
| SEO/aux tooling | next-seo, next-sitemap | small in-house equivalents |
The last row is the subtle win: because each module gets its own content-hashed chunk, shipping a change to billing only invalidates that chunk — returning users "download kilobytes, not megabytes."
The twist: others say Turbopack gets you there too
In the Hacker News discussion, one of the most important comments: "Are you on turbopack? It's available on Next 16 and just took our build times down from 6 minutes to 2 minutes." Another commenter moved from Next.js to React Router and saw deployments drop from 7-8 minutes to 1-2 minutes.
Same numbers, two different answers: stay + Turbopack, or leave + Vite. Railway noted in the HN thread they had tried Turbopack before moving. The practical takeaway:
- If your app is server-centric (Server Components, ISR, blog/shop content), migrating to TanStack makes little sense — Next.js 16.4 with Turbopack and Cache Components solves the build-time pain far more cheaply.
- If your app is dashboard-like, fully client-side, and builds still crawl past several minutes, the Railway post is a working roadmap.
When migration makes no sense
Before deciding, put yourself in Railway's shoes: their product is ~90% client. If yours is SEO-driven (blog, shop, landing pages) or leans on Server Actions and use cache, migration means throwing away your main advantage. TanStack's own comparison confirms the trade: RSC support in Start is experimental and opt-in, while it's the core model of the App Router. Even the official "TanStack Start vs Next.js" doc frames it as a fit question — Start for typed navigation and URL state, Next.js for the Server Component model and integrated image/font/metadata tools.
Decision checklist
- [ ] Have you profiled the production build and identified which stage eats the time?
- [ ] Are you on Turbopack (default since Next 16) or still on webpack? Cheapest win lives here.
- [ ] What percentage of your app genuinely needs server rendering? List it route by route.
- [ ] Do you use Server Actions,
use cache, or ISR? If yes, migration is almost always a step backward. - [ ] Have you inventoried your
next/*dependencies? A long list means Railway's PR 1 costs you more. - [ ] Have you run a two-day spike with Vite + TanStack Start on one non-critical route — before, not after, the framework decision?
Q: Doesn't Next.js 16.4 fix heavy builds?
Not solved — the tooling changed. Turbopack is default since 16, and multiple HN users report drops from 6-7 minutes to ~2. But if builds still crawl on Turbopack and your app is client-side, migration is a legitimate conversation.
Q: Is TanStack Start production-ready?
Per the official docs, it's at the Release Candidate stage: the API is described as feature-complete and stable, but it hasn't hit v1 and rough edges remain. Railway accepted that knowingly and sponsors both Vite and TanStack.
Q: Does this apply to shops or corporate sites?
Usually no. SEO-driven sites depend on SSR/ISR and Next.js's integrated image/metadata handling — the exact opposite of Railway's client-heavy dashboard. Where Vite/TanStack makes sense is typically internal tools and apps, not public content sites.