비교 | TanStack Start vs Next.js vs React Router
풀스택 React 프레임워크를 선택하고 계신가요? 이 비교는 TanStack Start를 Next.js와 React Router (v7 Framework Mode)와 구분하는 풀스택 프레임워크 기능에 초점을 맞춥니다.
🚨 중요: 라우팅 기능을 찾고 계신가요?
TanStack Start는 업계 최고 수준의 타입 안전 라우팅 기능을 제공하는 TanStack Router를 기반으로 합니다. 중첩된 라우트, 검색 매개변수, 타입 안전성, 로더 등 라우팅 기능에 대한 종합 비교는 다음을 확인하세요:
📖 TanStack Router와 React Router / Next.js 비교 →
그 비교에서는 모든 라우팅 기능을 자세히 다룹니다. 이 페이지는 SSR, 서버 함수, 미들웨어, 배포 등과 같은 풀스택 프레임워크 기능에 특히 초점을 맞춥니다.
정확하고 공정한 비교를 제공하려고 하지만, 이 표가 각 프레임워크의 모든 뉘앙스나 최근 업데이트를 반영하지는 못할 수 있습니다. 특정 사용 사례에 대해 가장 충분한 정보를 바탕으로 결정할 수 있도록 공식 문서를 검토하고 각 솔루션을 직접 사용해 보시기를 권장합니다.
차이점이나 개선 제안을 발견하시면, 이 페이지 하단의 "GitHub에서 이 페이지 편집" 링크를 통해 기여하시거나 TanStack Router GitHub 저장소에서 이슈를 열어 주시기 바랍니다.
기능/역량 범례:
- ✅ 기본 제공되며, 추가 설정이나 코드 없이 바로 사용할 수 있습니다
- 🟡 부분 지원(표시된 경우 1~5점)
- 🟠 애드온/커뮤니티 패키지를 통해 지원됩니다
- 🔶 가능하지만, 사용자 정의 코드/구현/캐스팅이 필요합니다
- 🛑 공식적으로 지원되지 않습니다
| TanStack Start | Next.js (웹사이트) | React Router (웹사이트) | |
|---|---|---|---|
| GitHub 저장소 / Stars | |||
| 번들 크기 | ❓ | ❓ | |
| -- | -- | -- | -- |
| 라우팅 기능 (전체 비교 보기) | ✅ TanStack Router를 기반으로 구축됨 | ✅ 파일 기반 App Router | ✅ 파일 기반 중첩 라우트 |
| -- | -- | -- | -- |
| 풀스택 기능 | -- | -- | -- |
| SSR | ✅ | ✅ | ✅ |
| 스트리밍 SSR | ✅ | ✅ | ✅ |
| 선택적 SSR(라우트별) | ✅ | 🔶 | 🔶 |
| SPA 모드 | ✅ | 🔶 ("use client"를 통해) | ✅ |
| 내장 클라이언트 측 SWR 캐싱 | ✅ (TanStack Router를 통해) | 🔶 (fetch 캐시만) | 🛑 |
| 데이터 패칭 라이브러리 통합 | ✅ (공식 TanStack Query, Apollo 등) | 🔶 (수동 통합) | 🔶 (수동 통합) |
| 정적 사전 렌더링(SSG) | ✅ | ✅ | ✅ |
| 점진적 정적 재생성(ISR) | ✅ (Cache-Control 헤더를 통해) | ✅ (독점) | ✅ (Cache-Control 헤더를 통해) |
| React Server Components | 🟡 (실험적) | ✅ | 🟡 (실험적) |
| 서버 함수 | ✅ (RPC 기반) | ✅ (Server Actions) | ✅ (Actions) |
| 서버 함수 클라이언트 미들웨어 | ✅ | 🛑 | 🛑 |
| 서버 함수 서버 미들웨어 | ✅ | 🛑 | ✅ |
| 요청 미들웨어(모든 라우트) | ✅ | ✅ | ✅ |
| 서버 함수 입력 검증 | ✅ | 🔶 (수동) | 🔶 (수동) |
| API 라우트 / 서버 라우트 / 리소스 라우트 | ✅ | ✅ | ✅ |
<Form> API | 🛑 | 🟠 (React 19 useActionState를 통해) | ✅ |
| -- | -- | -- | -- |
| 개발자 경험 | -- | -- | -- |
| Devtools | ✅ | 🛑 | 🟠 (3rd party) |
| CLI 도구 | ✅ | ✅ | ✅ |
| Dev 서버 시작 속도 | ✅ (빠름) | 🛑 (느림) | ✅ (빠름) |
| HMR 속도 | ✅ (빠름, Vite 또는 Rsbuild) | 🛑 (느림, Webpack/Turbopack) | ✅ (빠름, Vite) |
| Dev 탐색 속도 | ✅ | 🟡 | ✅ |
| Dev 리소스 사용량(CPU/RAM) | ✅ (가벼움) | 🛑 (무거움) | ✅ (가벼움) |
| TypeScript 지원 | ✅ | ✅ | ✅ |
| 타입 우선 아키텍처 | ✅ | 🛑 | 🛑 |
| -- | -- | -- | -- |
| 배포 및 호스팅 | -- | -- | -- |
| 배포 유연성 | ✅ (Vite 및 Rsbuild 빌드) | 🟡 (Vercel에 최적화, 다른 곳에서도 가능) | ✅ (여러 어댑터) |
| 엣지 런타임 지원 | ✅ | ✅ | ✅ |
| 서버리스 지원 | ✅ | ✅ | ✅ |
| Node.js 지원 | ✅ | ✅ | ✅ |
| Docker 지원 | ✅ | ✅ | ✅ |
| 정적 내보내기 | ✅ | ✅ | ✅ |
| 공식 Cloudflare 지원 | ✅ | 🟡 | ✅ |
| 공식 Netlify 지원 | ✅ | 🟡 | ✅ |
| 공식 Vercel 지원 | ✅ (Nitro를 통해) | ✅ | ✅ |
⚠️ 기억하세요: 라우팅 기능(타입 안전성, 검색 매개변수, 로더, 탐색 등)의 자세한 비교는 TanStack Router 비교를 참조하세요. 이 페이지는 풀스택 프레임워크 기능에 중점을 둡니다.
핵심 철학적 차이
TanStack Start
철학: 최고 수준의 타입 안전성과 최대의 개발자 자유를 제공합니다.
- Router-First: TanStack Router를 기반으로 합니다(full routing comparison 참조)
- 배포 독립적: Vite 및 Rsbuild 통합을 기반으로 하며, 벤더 종속성 없이 배포합니다
- 조합 가능한 미들웨어: 미들웨어 시스템은 요청 수준과 개별 서버 함수 수준 모두에서 작동합니다(클라이언트와 서버 모두)
- 선택적 SSR: 라우트별로 SSR 동작을 세밀하게 제어합니다(전체 SSR, 데이터 전용, 또는 클라이언트 전용)
- 개발자 제어: 규칙 기반 마법보다 명시적이고 조합 가능한 패턴을 사용합니다
- 타입 안전성 우선: 서버 함수, 로더, 라우팅 전반에 걸친 컴파일 시점 종단 간 안전성을 제공합니다
Next.js
철학: 최적의 기본값으로 바로 프로덕션에 사용할 수 있으며, Vercel과 가장 잘 맞습니다.
- RSC 우선: React Server Components와의 깊은 통합을 핵심 패러다임으로 사용합니다
- Vercel 최적화: Vercel의 인프라에서 최고의 성능과 DX를 제공합니다
- 구성보다 규칙 우선: 파일 시스템 라우팅 규칙을 따르는 의견이 강한 구조를 사용합니다
- 자동 최적화: 많은 성능 최적화가 자동으로 이루어집니다
- 프로덕션급: 대규모 환경에서 검증되었습니다
React Router (v7 Framework Mode)
철학: 점진적 향상이 적용된 웹의 기본 원칙을 따릅니다.
- 웹 표준: 웹 플랫폼 원시 요소(fetch, FormData, Headers)를 적극 활용합니다
- 점진적 향상: 기본적으로 JavaScript 없이도 작동합니다
- 중첩 라우트: 중첩 라우팅과 데이터 로딩을 1급으로 지원합니다
- 액션 기반: actions를 통한 폼 제출은 웹 표준을 따릅니다
- 프레임워크 진화: Remix의 후속으로, Vite 기반 아키텍처를 사용합니다
각 프레임워크를 선택해야 하는 경우
다음과 같은 경우 TanStack Start를 선택합니다:
- 라우팅에 대해 절대적으로 최고의 타입 안전성을 원합니다(Router Comparison 참조)
- 벤더 종속 없이 배포 유연성이 필요합니다(Vite 및 Rsbuild 빌드에서 동작합니다)
- 관례보다 조합 가능하고 명시적인 패턴을 선호합니다
- SSR 동작을 세밀하게 제어하고 싶습니다(라우트별 선택적 SSR)
- 요청 수준과 server function 수준 모두에서 동작하는 조합 가능한 middleware가 필요합니다
- TanStack Router의 고급 기능이 유용한 복잡한 애플리케이션을 만들고 있습니다
- 이미 TanStack Query 또는 다른 TanStack 라이브러리를 사용하고 있습니다
다음 경우 Next.js를 선택합니다:
- 오늘 바로 전체 에코시스템 지원과 함께 React Server Components를 사용하고 싶습니다
- Vercel에 배포 중이거나 Vercel에 최적화된 경험을 원합니다
- 더 빠른 초기 개발을 위해 configuration보다 convention을 선호합니다
- 자동 이미지 최적화와 font loading을 원합니다
다음 경우 React Router를 선택합니다:
- progressive enhancement를 우선합니다
- JavaScript 없이도 앱이 동작하길 원합니다
- 웹 convention을 따르는 action 기반 mutation을 선호합니다
기능 심층 살펴보기
내장 클라이언트 측 캐싱
TanStack Start는 TanStack Router를 통해 강력한 내장 SWR(stale-while-revalidate) 캐싱을 제공합니다:
- 즉시 사용 가능한 성능 - loader 데이터가 자동으로 캐시되고 revalidation됩니다
- 세밀한 제어 - 라우트별로
staleTime,gcTime, 그리고 revalidation을 구성합니다 - 구조적 공유 - 변경된 것만 효율적으로 다시 렌더링하는 업데이트
- 공식 통합 - TanStack Query, Apollo, 그리고 다른 data fetching 라이브러리를 바로 지원합니다
- 더 뛰어난 성능 - 즉시 navigation과 background updates로 사용자 경험에 최적화되어 있습니다
export const Route = createFileRoute('/posts/$postId')({
loader: async ({ params }) => fetchPost(params.postId),
staleTime: 10_000, // Consider fresh for 10 seconds
gcTime: 5 * 60_000, // Keep in memory for 5 minutes
})
고급 시나리오에서는 TanStack Start가 TanStack Query와 매끄럽게 통합됩니다:
import { queryOptions } from '@tanstack/react-query'
const postQueryOptions = (postId: string) =>
queryOptions({
queryKey: ['post', postId],
queryFn: () => fetchPost(postId),
})
export const Route = createFileRoute('/posts/$postId')({
loader: ({ context, params }) =>
context.queryClient.ensureQueryData(postQueryOptions(params.postId)),
})
function Post() {
const { postId } = Route.useParams()
const { data } = useQuery(postQueryOptions(postId))
// Automatically uses cached data from loader
}
Next.js는 기본적인 fetch 캐싱은 제공하지만 세밀한 제어가 부족하고 React Query 같은 라이브러리와의 수동 통합이 필요합니다.
React Router에는 내장 클라이언트 측 캐싱이 없습니다. 캐싱 솔루션을 수동으로 통합해야 합니다.
서버 함수와 서버 액션 비교
TanStack Start Server Functions:
export const getTodos = createServerFn({ method: 'GET' })
.validator(zodValidator(z.object({ userId: z.string() })))
.middleware([authMiddleware])
.handler(async ({ data, context }) => {
// Fully typed data and context
return db.todos.findMany({ where: { userId: data.userId } })
})
// Call from anywhere with full type safety
const todos = await getTodos({ data: { userId: '123' } })
Next.js Server Actions:
'use server'
export async function getTodos(userId: string) {
// Runs on server, called from client
return db.todos.findMany({ where: { userId } })
}
// Call from client component
const todos = await getTodos('123')
주요 차이점:
- Start의 server functions는 client와 server middleware를 모두 지원합니다
- Start에는 입력 검증이 내장되어 있습니다
- Start의 접근 방식은 client/server 경계에 대해 더 명시적입니다
- Start의 server functions는
method옵션을 통해 구성 가능한 GET과 POST를 모두 지원하며, 기본값은 GET입니다. 반면 Next.js Server Actions는 POST만 지원합니다. - Next.js Server Actions는 forms와 더 매끄럽게 통합됩니다
Middleware 아키텍처
TanStack Start에는 두 가지 유형의 middleware가 있습니다:
- Request Middleware: 모든 요청(SSR, API routes, server functions)에 대해 실행됩니다
- Server Function Middleware: server functions에 대해 특정적으로 실행되며, client-side와 server-side 실행을 모두 지원합니다
이러한 조합 가능성 덕분에 다음이 가능합니다:
const authMiddleware = createMiddleware({ type: 'function' })
.client(async ({ next }) => {
// Run auth checks on client
return next({
headers: { Authorization: `Bearer ${getToken()}` },
})
})
.server(async ({ next }) => {
// Validate auth on server
return next({ context: { user: await getUser() } })
})
Next.js에는 Node.js runtime에서 실행되는 단일 proxy.ts 파일이 있습니다. 더 이상 사용되지 않는 middleware.ts(Edge Runtime에서 실행됨)와 달리 proxy.ts는 데이터베이스 같은 server-side 리소스에 전체 접근 권한을 가집니다.
배포 유연성
TanStack Start는 현대적인 build tool 에코시스템을 활용합니다:
- Cloudflare Workers, Netlify, Vercel, Railway, Fly.io, AWS 등으로 배포합니다
- 범용 배포 지원을 위해 Nitro를 사용합니다
- 벤더 고유 기능이나 종속성이 없습니다
- 동일한 codebase가 어디서나 동작합니다
Next.js는 Vercel에 최적화되어 있습니다:
- 많은 기능이 Vercel에서 가장 잘 동작하거나 Vercel에서만 동작합니다(ISR, Image Optimization, Middleware)
- self-hosting에는 더 많은 configuration이 필요합니다
- 다른 플랫폼으로의 배포에는 제한이 있을 수 있습니다
React Server Components (RSC)
현재 상태:
- Next.js: 광범위한 에코시스템과 함께 완전한 production 지원
- TanStack Start: 실험적 지원 제공
- React Router: 실험적 지원 제공
TanStack Start의 RSC 구현은 client-led composition 접근 방식을 취합니다. server components는 client가 가져오고, 캐시하고, 조합할 수 있는 data로 취급됩니다. 자세한 내용은 Server Components 가이드를 참조하세요.
성능 고려 사항
production 성능
세 프레임워크 모두 뛰어난 production 성능과 최고 수준의 Lighthouse 점수를 달성할 수 있습니다. 차이는 최적화 전략에 달려 있습니다:
- TanStack Start: 최적화된 bundler 빌드, SWR 캐싱으로 server load 감소, 경량 runtime
- Next.js: 자동 code splitting, image optimization, 그리고 내장 성능 기능
- React Router: 웹 표준 기반 캐싱과 최적화
개발 성능
여기서 프레임워크 간 차이가 크게 드러납니다:
TanStack Start & React Router:
- ⚡ 즉시 dev server 시작 - Vite와 Rsbuild가 빠르게 시작됩니다
- ⚡ 번개처럼 빠른 HMR - 페이지 새로고침 없이 변경 사항이 즉시 반영됩니다
- ⚡ 빠른 dev navigation - 개발 중에도 전체 속도 routing이 가능합니다
- ⚡ 가벼운 리소스 사용량 - CPU와 RAM 소모가 최소입니다
- ⚡ 높은 개발 처리량 - 많은 동시 요청을 효율적으로 처리합니다
Next.js:
- 🐌 느린 dev server 시작 - 특히 큰 프로젝트에서는 시작에 몇 초가 걸릴 수 있습니다
- 🐌 느린 HMR - Turbopack을 사용해도 hot reloading이 눈에 띄게 느립니다
- 🐌 제한된 dev navigation - 개발 중 navigation이 의도적으로 느려집니다
- 🐌 무거운 리소스 사용량 - 개발 중 CPU와 RAM 소모가 큽니다
왜 이것이 중요한가:
개발 성능은 개발자 생산성에 직접적인 영향을 줍니다. 더 빠른 피드백 루프는 다음을 의미합니다:
- 시간당 더 많은 반복 작업
- 더 나은 몰입 상태와 집중
- 더 낮은 머신 요구 사항
- 개발 중 좌절감 감소
- development build를 위한 더 빠른 CI/CD pipeline
Next.js의 production 성능은 뛰어나지만, 특히 큰 codebase나 덜 강력한 머신에서는 개발 경험이 눈에 띄게 더 느릴 수 있습니다.
커뮤니티와 에코시스템
- Next.js: 가장 큰 커뮤니티, 가장 많은 third-party 통합, 방대한 학습 자료
- React Router: 가장 오래되고 널리 사용되는 React 라이브러리 중 하나, 강력한 커뮤니티, 뛰어난 문서
- TanStack Start: 성장 중인 커뮤니티, TanStack 에코시스템의 일부, 뛰어난 Discord 지원
성숙도
- Next.js: 프로덕션 준비 완료, 수천 개의 회사에서 사용되며 대규모에서 검증되었습니다
- React Router: 프로덕션 준비 완료, 수백만 개의 앱을 구동하며, v7 Framework Mode는 Remix의 진화입니다
- TanStack Start: 릴리스 후보 단계, 기능이 완성되었고 v1을 향해 빠르게 안정화되고 있습니다