호스팅
호스팅은 사용자가 애플리케이션에 접근할 수 있도록 인터넷에 배포하는 과정입니다. 이는 모든 웹 개발 프로젝트에서 매우 중요한 부분으로, 애플리케이션을 전 세계에서 사용할 수 있도록 합니다. TanStack Start는 Vite와 Rsbuild를 지원하여 다양한 호스팅 제공업체와 런타임에 맞는 유연한 빌드 출력을 제공합니다.
무엇을 사용해야 하나요?
TanStack Start는 모든 호스팅 제공업체와 함께 작동하도록 설계되었으므로, 이미 염두에 둔 호스팅 제공업체가 있다면 TanStack Start가 제공하는 풀스택 API를 사용하여 해당 제공업체에 애플리케이션을 배포할 수 있습니다.
하지만 호스팅은 애플리케이션의 성능, 안정성, 확장성에서 가장 중요한 요소 중 하나이므로 공식 호스팅 파트너인 Cloudflare, Netlify 또는 Railway 중 하나를 사용하는 것을 권장합니다.
배포
배포 대상을 선택한 후 아래 배포 지침에 따라 원하는 호스팅 제공업체에 TanStack Start 애플리케이션을 배포할 수 있습니다:
cloudflare-workers: Cloudflare Workers에 배포합니다netlify: Netlify에 배포합니다railway: Railway에 배포합니다nitro: Nitro를 사용하여 배포합니다vercel: Vercel에 배포합니다node-server: Node.js 서버에 배포합니다bun: Bun 서버에 배포합니다appwrite-sites: Appwrite Sites에 배포합니다- ... 앞으로 더 많이 추가될 예정입니다!
Cloudflare Workers ⭐ 공식 파트너 {#cloudflare-workers--official-partner}
Cloudflare Workers에 배포할 때는 사용자가 앱을 사용하기 전에 몇 가지 추가 단계를 완료해야 합니다.
공식 Cloudflare Workers 설정은 현재 @cloudflare/vite-plugin을 통해 Vite를 사용합니다.
@cloudflare/vite-plugin과wrangler을 설치합니다
pnpm add -D @cloudflare/vite-plugin wrangler
vite.config.ts파일에 Cloudflare 플러그인을 추가합니다
// vite.config.ts
import { defineConfig } from 'vite'
import { tanstackStart } from '@tanstack/react-start/plugin/vite'
import { cloudflare } from '@cloudflare/vite-plugin'
import viteReact from '@vitejs/plugin-react'
export default defineConfig({
plugins: [
cloudflare({ viteEnvironment: { name: 'ssr' } }),
tanstackStart(),
viteReact(),
],
})
wrangler.jsonc구성 파일을 추가합니다
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "tanstack-start-app",
"compatibility_date": "2025-09-02",
"compatibility_flags": ["nodejs_compat"],
"main": "@tanstack/react-start/server-entry"
}
package.json파일의 스크립트를 수정합니다
{
"scripts": {
"dev": "vite dev",
"build": "vite build && tsc --noEmit",
// ============ 👇 remove this line ============
"start": "node .output/server/index.mjs",
// ============ 👇 add these lines ============
"preview": "vite preview",
"deploy": "npm run build && wrangler deploy",
"cf-typegen": "wrangler types"
}
}
- Cloudflare 계정으로 인증하기 위해 Wrangler로 로그인합니다.
npx wrangler login
또는 pnpm을 사용하는 경우:
pnpm dlx wrangler login
현재 사용자를 확인하려면 wrangler whoami을 사용합니다.
- 배포합니다
pnpm run deploy
Cloudflare Workers의 원클릭 배포 절차를 사용하여 애플리케이션을 배포하면 모든 준비가 완료됩니다!
Cloudflare Workers용 전체 TanStack Start 예제는 여기에서 확인할 수 있습니다.
Netlify ⭐ 공식 파트너 {#netlify--official-partner}
공식 Netlify 설정은 현재 @netlify/vite-plugin-tanstack-start을 통해 Vite를 사용하며, 이 플러그인은 Netlify 배포에 맞게 빌드를 구성하고 로컬 개발 환경에서 Netlify 프로덕션 플랫폼을 완전히 에뮬레이션합니다:
npm install --save-dev @netlify/vite-plugin-tanstack-start
# or...
pnpm add --save-dev @netlify/vite-plugin-tanstack-start
# or yarn, bun, etc.
// vite.config.ts
import { defineConfig } from 'vite'
import { tanstackStart } from '@tanstack/react-start/plugin/vite'
import netlify from '@netlify/vite-plugin-tanstack-start' // ← add this
import viteReact from '@vitejs/plugin-react'
export default defineConfig({
plugins: [
tanstackStart(),
netlify(), // ← add this (anywhere in the array is fine)
viteReact(),
],
})
마지막으로 Netlify CLI를 사용하여 앱을 배포합니다:
npx netlify deploy
새 Netlify 프로젝트인 경우 초기화하라는 메시지가 표시되며 빌드 설정이 자동으로 구성됩니다.
더 자세한 문서는 전체 Netlify의 TanStack Start 문서를 확인하세요.
수동 구성
또는 수동 구성을 선호하는 경우 프로젝트 루트에 netlify.toml 파일을 추가할 수 있습니다:
[build]
command = "vite build"
publish = "dist/client"
[dev]
command = "vite dev"
port = 3000
또는 위 설정을 Netlify 앱에서 직접 지정할 수 있습니다.
기타 배포 방법
Netlify는 git 저장소에서 지속적 배포 GitHub, GitLab 또는 기타 서비스에 호스팅, 템플릿으로 시작, AI 코드 생성 도구에서 배포하거나 가져오기 및 기타 방법도 지원합니다.
Railway ⭐ 공식 파트너 {#railway--official-partner}
Railway는 구성 없이 즉시 배포할 수 있도록 지원합니다. Nitro 배포 지침을 따른 후 Railway에 배포합니다:
-
코드를 GitHub 저장소에 푸시합니다
-
railway.com에서 저장소를 Railway에 연결합니다
-
Railway가 빌드 설정을 자동으로 감지하고 애플리케이션을 배포합니다
Railway는 다음 기능을 자동으로 제공합니다:
- 저장소에 푸시할 때마다 자동 배포
- 내장 데이터베이스(Postgres, MySQL, Redis, MongoDB)
- 풀 리퀘스트용 미리보기 환경
- 자동 HTTPS 및 사용자 지정 도메인
자세한 내용은 Railway 문서를 참조하세요.
Nitro
Nitro는 TanStack Start 애플리케이션을 다양한 호스팅 환경에 배포할 수 있게 해주는 독립적인 계층입니다.
⚠️ nitro/vite 플러그인은 TanStack Start의 기반 빌드 도구로 Vite Environments API와 네이티브 방식으로 통합됩니다. 아직 활발히 개발 중이며 정기적으로 업데이트됩니다. 문제가 발생하면 조사할 수 있도록 재현 방법과 함께 보고해 주세요.
nitro을 설치합니다:
npm install nitro
vite.config.ts파일에nitro/vite플러그인을 추가합니다:
import { tanstackStart } from '@tanstack/react-start/plugin/vite'
import { defineConfig } from 'vite'
import { nitro } from 'nitro/vite'
import viteReact from '@vitejs/plugin-react'
export default defineConfig({
plugins: [tanstackStart(), nitro(), viteReact()],
})
성능 팁: FastResponse
Nitro(내부적으로 srvx를 사용함)를 통해 Node.js에 배포하는 경우, 전역 Response 생성자를 srvx의 최적화된 FastResponse으로 교체하면 처리량을 약 5% 개선할 수 있습니다.
먼저 srvx를 설치합니다:
npm install srvx
그런 다음 서버 진입점(src/server.ts)에 다음을 추가합니다:
import { FastResponse } from 'srvx'
globalThis.Response = FastResponse
이는 srvx의 FastResponse에 표준 Web Response에서 Node.js로 변환할 때 발생하는 오버헤드를 방지하는 최적화된 _toNodeResponse() 경로가 포함되어 있기 때문입니다. 이 최적화는 Nitro/h3/srvx를 사용하는 Node.js 배포에만 적용됩니다.
Vercel
Nitro 배포 지침을 따릅니다.
원클릭 배포 절차를 사용하여 애플리케이션을 Vercel에 배포하면 모든 준비가 완료됩니다!
Node.js / Docker
빌드 도구에 맞는 Node.js 배포 형태를 사용합니다.
Vite
Nitro 배포 지침을 따릅니다. 빌드 출력 파일을 사용해 서버에서 애플리케이션을 시작하려면 node 명령을 사용합니다.
package.json 파일에 build 및 start npm 스크립트가 있는지 확인합니다:
"build": "vite build",
"start": "node .output/server/index.mjs"
Rsbuild
Rsbuild 프로덕션 빌드는 클라이언트 애셋을 dist/client에, 서버 번들을 dist/server/index.js에 출력합니다. 서버 번들은 fetch 스타일의 Start 서버 엔트리를 내보냅니다:
type ServerEntry = {
fetch(request: Request): Response | Promise<Response>
}
Node.js에서 실행하려면 dist/client을 정적 애셋으로 제공하고, 그 밖의 모든 요청은 서버 엔트리의 fetch 핸들러로 전달합니다. 이를 수행하는 한 가지 방법은 srvx입니다:
npm install srvx
"build": "rsbuild build",
"start": "srvx --prod -s ../client dist/server/index.js"
클라이언트 애셋을 제공하고 동적 요청에 대해 서버 엔트리의 fetch 핸들러를 호출하기만 하면 Express나 다른 커스텀 Node.js 서버도 사용할 수 있습니다.
서버 엔트리가 dist/server/server.js으로 출력되는 경우 dist/server/index.js 대신 해당 경로를 사용합니다.
그런 다음 다음 명령어를 실행하여 애플리케이션을 빌드할 수 있습니다:
npm run build
다음을 실행하여 애플리케이션을 시작할 수 있습니다:
npm run start
Bun
[!IMPORTANT] 현재 Bun 전용 배포 지침은 React 19에서만 작동합니다. React 18을 사용하는 경우 Node.js 배포 지침을 참조하세요.
package.json 파일에서 react 및 react-dom 패키지가 19.0.0 이상 버전으로 설정되어 있는지 확인합니다. 그렇지 않다면 다음 명령어를 실행하여 패키지를 업그레이드합니다:
bun install react@19 react-dom@19
Vite 빌드의 경우 Nitro 배포 지침을 따릅니다.
빌드를 호출하는 방식에 따라 Nitro 구성에서 'bun' 프리셋을 설정해야 할 수 있습니다:
// vite.config.ts
import { tanstackStart } from '@tanstack/react-start/plugin/vite'
import { defineConfig } from 'vite'
import { nitro } from 'nitro/vite'
import viteReact from '@vitejs/plugin-react'
export default defineConfig({
plugins: [tanstackStart(), nitro({ preset: 'bun' }), viteReact()],
})
Bun을 사용하는 프로덕션 서버
또는 Bun의 네이티브 API를 활용하는 커스텀 서버 구현을 사용할 수 있습니다.
프로덕션에 바로 사용할 수 있는 Bun 서버를 구축하는 한 가지 접근 방식을 보여주는 참조 구현을 제공합니다. 이 예제는 최적의 성능을 위해 Bun 네이티브 함수를 사용하며 지능형 애셋 사전 로딩과 메모리 관리 같은 기능을 포함합니다.
이것은 시작점입니다. 필요에 맞게 자유롭게 조정하거나 사용 사례에 맞게 단순화하세요.
이 예제에서 보여주는 내용:
- Bun의 네이티브 파일 처리를 사용하여 정적 애셋 제공
- 하이브리드 로딩 전략(작은 파일은 사전 로드하고 큰 파일은 요청 시 제공)
- ETag 지원 및 Gzip 압축과 같은 선택적 기능
- 프로덕션에 바로 사용할 수 있는 캐싱 헤더
빠른 설정:
-
예제 저장소의
server.ts파일을 프로젝트 루트에 복사합니다(또는 자체 구현을 위한 참고 자료로 사용합니다) -
애플리케이션을 빌드합니다:
bun run build -
서버를 시작합니다:
bun run server.ts
구성(선택 사항):
참조 서버 구현에는 환경 변수를 통한 여러 선택적 구성 옵션이 포함됩니다. 이를 그대로 사용하거나 수정할 수 있으며, 필요하지 않은 기능은 제거할 수 있습니다:
# Basic usage - just works out of the box
bun run server.ts
# Common configurations
PORT=8080 bun run server.ts # Custom port
ASSET_PRELOAD_VERBOSE_LOGGING=true bun run server.ts # See what's happening
사용 가능한 환경 변수:
| 변수 | 설명 | 기본값 |
|---|---|---|
PORT | 서버 포트 | 3000 |
ASSET_PRELOAD_MAX_SIZE | 메모리에 미리 로드할 최대 파일 크기(바이트) | 5242880 (5MB) |
ASSET_PRELOAD_INCLUDE_PATTERNS | 포함할 파일의 쉼표로 구분된 glob 패턴 | 모든 파일 |
ASSET_PRELOAD_EXCLUDE_PATTERNS | 제외할 파일의 쉼표로 구분된 glob 패턴 | 없음 |
ASSET_PRELOAD_VERBOSE_LOGGING | 상세 로깅 활성화 | false |
ASSET_PRELOAD_ENABLE_ETAG | ETag 생성 활성화 | true |
ASSET_PRELOAD_ENABLE_GZIP | Gzip 압축 활성화 | true |
ASSET_PRELOAD_GZIP_MIN_SIZE | Gzip을 적용할 최소 파일 크기(바이트) | 1024 (1KB) |
ASSET_PRELOAD_GZIP_MIME_TYPES | Gzip을 적용할 수 있는 MIME 유형 | text/,application/javascript,application/json,application/xml,image/svg+xml |
고급 구성 예시
# Optimize for minimal memory usage
ASSET_PRELOAD_MAX_SIZE=1048576 bun run server.ts
# Preload only critical assets
ASSET_PRELOAD_INCLUDE_PATTERNS="*.js,*.css" \
ASSET_PRELOAD_EXCLUDE_PATTERNS="*.map,vendor-*" \
bun run server.ts
# Disable optional features
ASSET_PRELOAD_ENABLE_ETAG=false \
ASSET_PRELOAD_ENABLE_GZIP=false \
bun run server.ts
# Custom Gzip configuration
ASSET_PRELOAD_GZIP_MIN_SIZE=2048 \
ASSET_PRELOAD_GZIP_MIME_TYPES="text/,application/javascript,application/json" \
bun run server.ts
출력 예시:
📦 Loading static assets from ./dist/client...
Max preload size: 5.00 MB
📁 Preloaded into memory:
/assets/index-a1b2c3d4.js 45.23 kB │ gzip: 15.83 kB
/assets/index-e5f6g7h8.css 12.45 kB │ gzip: 4.36 kB
💾 Served on-demand:
/assets/vendor-i9j0k1l2.js 245.67 kB │ gzip: 86.98 kB
✅ Preloaded 2 files (57.68 KB) into memory
🚀 Server running at http://localhost:3000
완전히 작동하는 예시는 이 저장소의 TanStack Start + Bun 예시를 확인하세요.
Appwrite Sites
Appwrite Sites에 배포할 때는 몇 가지 단계를 완료해야 합니다:
- TanStack Start 앱을 생성합니다(또는 기존 앱을 사용합니다)
npx @tanstack/cli@latest create
- 프로젝트를 GitHub 저장소에 푸시합니다
GitHub 저장소를 생성하고 코드를 푸시합니다.
- Appwrite 프로젝트를 생성합니다
Appwrite Cloud로 이동하여 아직 가입하지 않았다면 가입한 다음, 첫 번째 프로젝트를 생성합니다.
- 사이트를 배포합니다
Appwrite 프로젝트의 사이드바에서 Sites 페이지로 이동합니다. Create site를 클릭하고 Connect a repository를 선택한 다음, GitHub 계정을 연결하고 저장소를 선택합니다.
-
프로덕션 브랜치와 루트 디렉터리를 선택합니다
-
프레임워크로 TanStack Start가 선택되어 있는지 확인합니다
-
빌드 설정을 확인합니다:
- 설치 명령어:
npm install - 빌드 명령어:
npm run build - 출력 디렉터리:
./dist(Nitro v2 또는 v3를 사용하는 경우에는./.output이어야 합니다)
- 설치 명령어:
-
필요한 환경 변수를 추가합니다
-
Deploy를 클릭합니다
배포가 성공하면 Visit site 버튼을 클릭하여 배포된 애플리케이션을 확인합니다.