콘텐츠로 이동

ADR-0008: Frontend: Bun + Vite + React

Umbra 의 사용자 대시보드와 웹 조인 페이지를 Bun + Vite + React SPA 로 구현한다.

Status

Accepted

  • Decided at — 2026-04-13
  • Decided by — Pablo

Context

Umbra 의 프론트엔드는 두 사용자 표면을 제공해야 한다.

  • Dashboard (app.umbra.ink) — 로그인 후 사용하는 인증된 대시보드
  • Web Join (join.umbra.ink/{slug}) — 외부에서 공유되는 멤버 가입 페이지

Pablo 의 이전 프로젝트(luxtra-bot, luxtra.dev)는 Next.js 15 + React 19 로 구현되었으나, Next.js 특유의 App Router 복잡도와 RSC 마법에 피로감이 누적되었다. Umbra 는 가볍고 빠른 부트스트래핑SSR 불필요 가 핵심 기준이다.

고려한 옵션:

  • Next.js 15 + React 19 (기존 Luxtra 팀 표준)
  • Vite + React SPA (Bun 런타임)
  • SvelteKit (React 피로감 해소 대안)
  • Hono + Vite + React (BFF 포함)
  • Astro (일부 SSR)

Decision

Bun + Vite + React 로 SPA 를 구성한다. 배포는 Vercel.

세부 선택:

  • Runtime — Bun (개발 서버, 패키지 매니저, 빌드)
  • Bundler — Vite
  • Framework — React 19
  • Rendering — SPA only (SSR 없음)

선택 근거:

  • 가장 단순한 조합 — 프론트엔드 백엔드 분리가 명확, 프로세스 1개
  • Dashboard 는 로그인 후 사용 → SEO 불필요 → SPA 로 충분
  • Web Join 의 OG 메타 는 Echo 서버가 User-Agent 기반으로 정적 HTML 반환 (간단한 트릭)
  • Bun 속도 이점 — npm install, 빌드, dev 서버 모두 Node 대비 빠름
  • Vite 의 DX — HMR, 빠른 빌드, 번들 크기 작음
  • React 생태계 — shadcn/ui, TanStack 계열, React Hook Form 등 SaaS 대시보드 도구가 풍부

Consequences

Positive

  • 배포 단위 단순 (정적 파일 한 덩어리)
  • 빌드 시간 단축으로 CI 부담 ↓
  • Next.js 피로감 해소 (App Router, RSC, Server Actions 마법 없음)
  • 백엔드-프론트엔드 책임 분리 명확 (Echo 가 API, React 가 UI)

Negative

  • Web Join 의 OG 태그는 별도 구현 필요 (SPA 기본은 meta 가 JS 로 주입되어 크롤러 인식 부정확)
  • Next.js 생태계의 편의성 포기 (next/image, next/link 같은 것)
  • 초기 로딩 시 빈 화면 (작은 번들로 완화 가능)

Neutral

  • 루스트라의 다른 프로젝트(luxtra-bot, luxtra.dev)와 스택 분기. 디자인 토큰은 공유 가능하나 컴포넌트 재사용은 별도 이식 필요
  • Bun 런타임 버그나 호환성 이슈 발생 시 Node 로 fallback 가능

Alternatives considered

Alternative 1: Next.js 15 + React 19

Pros

  • Luxtra 팀 표준 일치
  • SSR/SSG 지원으로 OG 태그 자연 처리
  • 생태계 최대 규모

Cons

  • App Router 복잡도, RSC 마법
  • Pablo 의 Next.js 피로감
  • SSR 이 MVP 요구사항에 불필요
  • 배포 단위 복잡 (서버 프로세스 또는 Vercel serverless)

Why rejected — Umbra 는 로그인 후 사용하는 대시보드가 핵심이라 SSR 가치 낮음. 단순성 우선.

Alternative 2: SvelteKit (Svelte 5)

Pros

  • React 피로감 해소 가능
  • 컴파일 타임 프레임워크로 번들 작음
  • Svelte 5 runes 로 Hook 불편함 해소

Cons

  • shadcn-svelte 가 React 대비 미성숙
  • Luxtra 팀 내 경험 부재
  • 진욱의 학습 부담

Why rejected — React 생태계(shadcn/ui, TanStack) 성숙도가 SaaS 대시보드에 결정적. 새 프레임워크 학습 비용이 이번 프로젝트 목표와 맞지 않음.

Alternative 3: Hono + Vite + React (BFF)

Pros

  • Hono 가 BFF 로 세션/토큰 격리
  • Bun 풀 활용

Cons

  • 레이어 +1 (Hono 배포, Echo 와 책임 겹침)
  • Umbra 봇이 Go 라 Hono(TS) BFF 의 시너지 낮음
  • MVP 에 과도한 복잡도

Why rejected — Echo 단일 백엔드로 충분. Hono BFF 의 이점이 추가 레이어 비용 대비 작음.

Alternative 4: Astro + Islands

Pros

  • 정적 콘텐츠에 최적

Cons

  • Dashboard 는 풀 인터랙티브 SPA 가 필요 → Astro 의 장점 소멸
  • Island 가 거의 전체가 되면 Astro 이점 사라짐

Why rejected — Dashboard 중심 앱에는 부적합.

Compliance

  • apps/web/package.json 에 Bun workspace 멤버 등록
  • apps/web/vite.config.ts 가 빌드 진입점
  • Vercel 설정: Framework = Vite, Build command = bun run build
  • Node 전용 라이브러리 사용 시 Bun 호환성 검증 필수

Revisit triggers

  • Bun 런타임 프로덕션 이슈가 지속되면 Node 로 전환
  • SEO 가 중요해지는 공개 페이지 추가 시 Astro 또는 Next.js 부분 도입 검토
  • Dashboard 규모가 커져서 SPA 초기 로딩이 문제가 되면 code splitting 또는 MPA 재평가

References