본문 바로가기
C.W.K.
Stream
Lesson 07 of 07 · published

마지막 선택 — cwkPippa와 cwk-site, 언제 어떤 스택을 쓸까?

~22 min · case-study, cwkpippa, cwk-site, strategic

Level 0React 입문자
0 XP0/54 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
마지막 질문은 React를 아느냐가 아니라 언제 이 스택을 고르느냐야. cwkPippa의 Vite SPA와 cwk-site의 Next.js를 나란히 놓고 결정 기준을 정리해.

비교할 두 앱

cwkPippa는 Vite SPA 프런트엔드와 FastAPI 백엔드, SQLite·JSONL 저장소를 사용해. 아빠가 인증 뒤에 쓰는 실시간 대화 앱이라 공개 페이지와 SEO가 필요하지 않아.

cwk-site는 Next.js 16과 Supabase를 쓰는 공개 출판 플랫폼이야. 에세이, 퀘스트, Pippalog, council, art gallery를 검색 엔진과 첫 방문자에게 빠르게 보여 줘야 하고, 일부 admin 화면만 인증 뒤에 있어.

스택을 나란히 놓기

관심사cwkPippacwk-site
라우팅React Router의 클라이언트 라우팅App Router의 파일 기반 라우팅
렌더링클라이언트 렌더링RSC, SSR, ISR
데이터fetch, SSE, useChatServer Component의 DB 조회와 Server Action
인증OAuth를 쓰는 1인 앱Supabase Auth를 쓰는 다중 사용자 앱
배포Mac Studio의 launchd와 TailscaleVercel의 git push 배포와 PR preview
상태 저장SQLite, JSONL, ChromaDBSupabase PostgreSQL, Cloudflare CDN
SEO필요 없음공개 콘텐츠에 중요함
첫 응답 속도우선순위가 낮음방문자의 첫인상이라 중요함

간단한 결정 기준

  1. 공개 콘텐츠와 SEO가 핵심이면 Next.js 같은 메타 프레임워크가 잘 맞아.
  2. Tauri나 Electron 안에서 실행할 데스크톱 앱이면 Vite SPA가 단순해.
  3. 모든 사용자가 로그인 뒤에 들어오는 상태 중심 앱이라면 SSR의 이득이 작을 수 있어.
  4. 채팅과 실시간 데이터 같은 무거운 상호작용은 두 스택 모두 처리할 수 있으니 다른 조건으로 골라.
  5. 작은 팀이 서버 런타임 없이 정적 배포를 원한다면 Vite SPA의 운영 표면이 더 작아.

이 퀘스트가 채운 자리

이 퀘스트는 React 19의 클라이언트 기능, 클라이언트 액션, RSC 없이 쓰는 Suspense와 use(), Tauri로 이어지는 Vite SPA 경로를 한곳에 모았어. 내부 도구와 대시보드, 데스크톱 wrapper를 만들 준비는 여기서 끝나고, 공개 콘텐츠와 RSC가 필요한 앱은 next-js-quest에서 이어 가면 돼.

Cinder로 이어지는 다리

다가올 cwkCinder 퀘스트는 이 스택 위에 Rust와 Tauri를 얹어. 프런트엔드는 Vite, React 19, TypeScript, Tailwind v4를 그대로 쓰고, Rust와 Tauri가 네이티브 shell을 맡아. Photoshop 연동에는 UXP 플러그인이 더해져. 이 선수과목이 있으니 각 Cinder 퀘스트가 React 기초부터 되풀이할 필요가 없어.

이 퀘스트는 실제 corpus의 빈자리를 채워. 주변 퀘스트는 React 지식을 전제로 삼았지만 클라이언트 전용 React 19 스택을 처음부터 끝까지 다루는 선수과목은 없었어. 이제 Cinder와 Tauri 계열 퀘스트가 공유할 토대가 생겼고, cwkPippa가 걸어온 Vite SPA 경로도 직접 따라갈 수 있어.

마무리

좋은 스택은 추상적으로 더 멋진 스택이 아니라 프로젝트의 실제 제약에 맞는 스택이야. 결정 기준을 적었으면 이제 그 선택으로 하나를 만들어 봐.

첫 응답 시간도 선택 기준이야

공개 방문자가 검색에서 들어오는 사이트는 TTFB와 첫 HTML에 담긴 콘텐츠가 첫인상과 검색 노출에 영향을 줘. 로그인 뒤 오래 사용하는 도구는 첫 문서보다 이후 상호작용과 로컬 상태가 더 중요할 수 있어. 같은 React라도 사용자가 처음 만나는 경로가 다르면 적합한 런타임도 달라져.

Code

나란히: 두 스택의 같은 '리스트 로드' 패턴·tsx
// cwk-site (Next.js) — 서버 컴포넌트, 요청 중 서버에서 실행돼
// app/conversations/page.tsx
import { db } from "@/lib/db";

export default async function ConversationsPage() {
  const conversations = await db.conversations.list(); // 직접 DB 쿼리
  return (
    <ul>
      {conversations.map((c) => <li key={c.id}>{c.title}</li>)}
    </ul>
  );
}
// SEO ✓, 서버 작업 ✓, 이 뷰에 클라이언트 JS 필요 없음, 다만 Node 런타임 + Next.js 빌드 파이프라인 필요

// cwkPippa (Vite SPA): Suspense와 use()를 쓰는 클라이언트 컴포넌트
// src/pages/ConversationsPage.tsx
import { use, Suspense } from "react";
import { fetchConversations } from "@/lib/api";

const promise = fetchConversations(); // 모듈 레벨 캐시

function List() {
  const conversations = use(promise);
  return (
    <ul>
      {conversations.map((c) => <li key={c.id}>{c.title}</li>)}
    </ul>
  );
}

export function ConversationsPage() {
  return (
    <Suspense fallback={<p>Loading…</p>}>
      <List />
    </Suspense>
  );
}
// 정적 배포 ✓, prod에 Node 런타임 없음 ✓, Tauri-친화 ✓, 다만 SEO 없음 + 렌더에 JS 필요

External links

Exercise

직접 만들고 싶은 프로젝트 하나를 골라 공개 콘텐츠와 SEO, 데스크톱 wrapper, 로그인 뒤 상태, 실시간 상호작용, 운영 복잡도를 차례로 적어. 마지막에 Vite SPA와 Next.js 중 하나를 고르고 결정적이었던 조건과 다음에 이어 갈 퀘스트를 함께 적어.
Hint
유행보다 실제 사용자를 봐. 세 명이 쓰는 내부 admin 도구에 RSC만 보고 Next.js를 고르면 과설계일 수 있고, 검색 유입이 필요한 공개 사이트에 익숙함만 보고 Vite를 고르면 필요한 서버 렌더링을 놓칠 수 있어.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.