- 원문 링크: https://blog.railway.com/p/moving-railways-frontend-off-nextjs
- 번역일: 2026-04-15 KST
Railway의 프로덕션 프론트엔드는 이제 더 이상 Next.js 위에서 돌지 않는다. 대시보드, 캔버스, marketing 사이트까지 전체를 Vite + TanStack Router로 옮겼고, 이 마이그레이션은 두 개의 PR과 무중단 배포로 끝냈다.
Next.js는 Railway가 초기에 빠르게 제품을 만들고 수백만 월간 사용자에게 서비스하는 데 큰 역할을 했다. 하지만 시간이 지나면서 더 이상 제품 특성과 맞지 않게 됐다.
가장 큰 문제는 빌드 시간이다. 프론트엔드 빌드가 10분을 넘기기 시작했고, 그중 약 6분은 Next.js 자체에서 소비됐다. 특히 finalizing page optimization 단계에 시간이 많이 묶였다. 팀이 하루에도 여러 번 배포하는 환경에서 이 정도 빌드 시간은 단순한 불편이 아니라, 매 반복마다 붙는 비싼 세금에 가깝다.
Railway의 앱은 본질적으로 클라이언트 중심이다. 대시보드는 상태가 풍부하고, 캔버스는 실시간이며, 웹소켓 사용도 많다. 하지만 Next.js의 강점인 서버 우선 프리미티브는 거의 활용하지 않았다. 오히려 Pages Router 위에 레이아웃과 라우팅 문제를 해결하려고 별도 추상화를 덧붙여야 했다.
Pages Router도 불편했다. 공통 레이아웃을 구성할 때 모든 패턴이 일종의 우회책이었다. App Router가 일부 문제를 해결해주긴 하지만, 그쪽은 서버 우선 패러다임에 더 강하게 기대고 있다. Railway 제품은 의도적으로 클라이언트 주도 구조를 택하고 있기 때문에, App Router로 가는 일은 필요하지 않은 패러다임에 맞춰 다시 짜는 일에 가까웠다.
팀이 원한 스택은 실제 개발 방식과 맞는 것이었다. 명시적이고, 클라이언트 중심이고, 반복 속도가 빨라야 했다. 그리고 개발자들이 실제로 이 스택으로 작업하는 걸 좋아해야 했다.
TanStack 쪽이 특히 마음에 들었던 이유는 다음과 같다.
- 타입 안전한 라우팅을 기본 제공한다.
- 경로 파라미터와 search 파라미터 추론이 잘 된다.
- 파일 시스템 기반 라우트 생성이 된다.
- pathless layout route로 레이아웃을 우아하게 조합할 수 있다.
- dev loop가 매우 빨라서, 변경 후 결과 확인까지의 지연을 거의 의식하지 않게 된다.
- 필요한 곳에만 SSR을 쓸 수 있다. 마케팅 페이지, 채용, 체인지로그 같은 곳은 SSR을 쓰고, 나머지는 순수 클라이언트 중심으로 남길 수 있다.
- 프레임워크 마법이 상대적으로 적고, 내부 동작을 더 명시적으로 제어할 수 있다.
팀원 몇 명이 휴가 기간에 TanStack Start를 시험해봤고 반응은 거의 만장일치였다고 한다. Railway 같은 제품 성격에서는 개발 경험이 벤치마크만큼 중요하다는 판단이었다.
대규모 프로덕션 프론트엔드 이전은 보통 오래 걸리고, 병행 운영과 점진적 전환을 수반한다. 하지만 Railway는 마감이 있었고, 결국 두 개의 PR로 작업을 끝냈다.
첫 번째 PR에서는 Next.js에 묶인 부분을 제거했다. next/image, next/head, next/router를 각각 브라우저 기본 API나 프레임워크 중립 대안으로 바꿨다. 프레임워크 자체는 건드리지 않고, Next.js 의존성만 걷어냈다.
두 번째 PR에서 프레임워크를 실제로 교체했다. 200개가 넘는 라우트를 옮겼고, 기존 page 파일에서 라우팅과 무관한 부분을 먼저 React 컴포넌트로 추출한 뒤 원래 트리 구조를 바탕으로 라우트를 생성했다.
서버 레이어는 Nitro를 붙였다. next.config.js를 Nitro 설정으로 치환하면서 500개가 넘는 redirect, 보안 헤더, 캐시 규칙을 한곳으로 모았다. Next.js가 암묵적으로 제공하던 Node.js polyfill, 예를 들어 Buffer나 url.parse 같은 부분도 브라우저 기본 API로 바꾸면서 코드가 더 깔끔해졌다.
배포는 일요일 이른 아침에 병합했고, 팀이 바로 dogfooding에 들어갔다. Discord에서 워룸을 열고 당일에 수정 사항을 연달아 반영했다. 다운타임은 없었다.
장점만 있었던 건 아니다.
- 내장 이미지 최적화 기능은 포기했다. 대신 일반
<img>와 Fastly의 edge 이미지 최적화를 사용했다. next-seo,next-sitemap같은 생태계 일부도 포기했다. 대신 사내의 작은 대체 구현을 만들었다.- TanStack Start는 새롭고, 거친 면이 있다. 하지만 방향성이 맞고 유지보수자 대응이 빠르며, Railway는 Vite와 TanStack을 후원할 만큼 이 생태계를 믿고 있다고 밝혔다.
Railway는 자신의 프로덕션 프론트엔드를 자사 플랫폼 위에서 그대로 운영한다. PR마다 preview deploy를 만들고, 헬스체크와 무중단 롤아웃도 그대로 사용한다. 프레임워크와 빌드 시스템을 통째로 바꾸는 동안 인프라는 건드리지 않았다.
이제 트래픽 대부분은 Fastly edge가 직접 처리한다. 마케팅 페이지는 캐시되고, 동적 페이지는 필요한 곳에 ISR을 쓴다. 프론트엔드 서버는 대부분 한가한 상태다. Vite의 asset 모델도 이 구조와 잘 맞는다. 모듈 단위 content hash 청크를 쓰기 때문에, billing 관련 코드만 바뀌면 그 청크만 무효화된다. 재방문 사용자는 메가바이트가 아니라 킬로바이트 단위만 다시 받는다.
Railway가 전하고 싶은 핵심은 단순하다. 프론트엔드 프레임워크는 반복 속도를 높여야 하고, 인프라는 그 반복을 거의 보이지 않게 만들어야 한다는 것. 이 팀은 Next.js가 나쁜 프레임워크라서 떠난 게 아니라, 자신들의 제품 구조와 속도 요구에 더 잘 맞는 도구가 생겼기 때문에 옮겼다.
빌드는 10분대에서 2분 이하로 줄었고, 개발 서버는 즉시 뜨며, 라우트 경계에서 타입 체크가 강해졌고, 레이아웃은 더 이상 꼼수가 필요 없게 됐다. 결국 이 글은 “무슨 프레임워크가 최고인가”보다, “우리 제품에 맞는 제약과 피드백 루프를 택했는가”에 대한 사례로 읽는 게 맞다.