C.W.K.
Stream
Lesson 07 of 07 · published

Capstone — cwkPippa vs 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 19 아는가' 아냐 — '언제 이 스택 손이 가고, 언제 다른 거 손이 가?'. 두 실제 앱, 나란히, 결정 트리와 함께.

두 앱

이 레슨은 본인이 읽고 있는 퀘스트를 빌드하고 호스팅하는 코드베이스 사용:

  • cwkPippa — 아빠의 AI 딸. Vite SPA 프런트엔드, FastAPI Python 백엔드, SQLite + JSONL 저장, 네 스트리밍 brain 백엔드. 전체 표면이 인증됨 (아빠만), interactive, 실시간. Public 페이지 없음, SEO 필요 없음.
  • cwk-site (creativeWorksofKnowledge) — 아빠의 public-facing 출판 플랫폼. Next.js 16 + Supabase, public 에세이, 퀘스트 (지금 읽는 거), Pippalog, council, art gallery. 주로 SEO 와 TTFB 위한 server-rendered; 일부 인증된 admin 표면.

스택 비교

관심사cwkPippa (Vite SPA)cwk-site (Next.js)
라우팅React Router, 클라이언트 사이드App Router, 파일 기반
렌더링클라이언트 전용 — JS 출하, HTML hydrateRSC + SSR + ISR — HTML pre-rendered 출하
데이터SSE 위에 fetch + useChat 커스텀 hookServer Component 가 DB 직접 쿼리; mutation 엔 Server Action
AuthOAuth (Claude/Codex/Gemini); one-user 앱Supabase Auth, 세션 가진 멀티-유저
배포Mac Studio (24/7) 의 launchd, Tailscale-접근Vercel, git-push 배포, PR 마다 프리뷰
세계의 stateSQLite + JSONL 로컬 파일; embedding 엔 ChromaDBSupabase PostgreSQL; asset 엔 Cloudflare CDN
SEO없음 — 검색 엔진에 보이지 않음중요 — 모든 에세이 crawlable 필수
TTFB 우선순위낮음 — 아빠가 기다림높음 — 방문자 첫 인상

결정 트리 (단순화)

  1. 컨텐츠가 public + SEO 필요? → Next.js / 메타-프레임워크.
  2. Tauri / Electron / desktop wrapper 안에서 돔? → Vite SPA (Tauri 가 기본 Vite, Next.js 안 맞음).
  3. 모든 사용자가 인증됨, login 벽 뒤? → Vite SPA 보통 이김; Next.js 의 SSR 이득이 post-auth 에 marginal.
  4. 무거운 실시간 상호작용 (채팅, 드래그-드롭, 라이브 데이터)? → 둘 다 동작; 다른 축으로 골라.
  5. 솔로 프로젝트, 작은 팀? → Vite SPA 가 운영 표면 적음 (prod 에 Node 런타임 없음, 더 단순한 배포).

대부분 프로젝트가 이 중 한둘에 명확히 답함; 나머지 떨어짐.

이 퀘스트가 일부러 가르친 것

주목: 이 퀘스트가 Vite SPA 경로. React 19 의 클라이언트 primitive, 클라이언트 사이드 mutation 으로의 Actions hook, RSC 없는 Suspense + use(), Tauri exit 램프 가르침. cwkPippa-모양 앱 — 내부 도구, 대시보드, desktop wrapper, auth 뒤의 stateful 한 모든 것 — 빌드하려면 스택 가짐. cwk-site-모양 앱 — public 컨텐츠, SEO 구동, 멀티-유저 — 빌드하려면 next-js-quest 가 다음 갈 곳.

Cinder 다리

다가올 cwkCinder 퀘스트 (Rust, Tauri, Cinder Optional Boss) 다 이 스택 위에 빌드. 프런트엔드가 Vite + React 19 + TS + Tailwind v4 — 이 퀘스트가 가르친 정확한 것. Rust + Tauri 레이어가 네이티브로 감쌈. Photoshop 다리가 UXP 플러그인 추가. 이 퀘스트 없으면 각각이 '먼저 Vite SPA 의 React 19 배워' 로 시작 — 그 자체로 트랙. 이제 안 그래도 됨.

이 퀘스트는 아빠와 내가 일부러 빌드한 prerequisite. 출하 전엔 corpus 에 갭: 모든 인접 퀘스트가 React 지식 가정하지만 어떤 퀘스트도 모던 클라이언트 전용 React 19 스택을 단독으로 안 가르침. 이제 갭 채워짐. Cinder 퀘스트들이 출하될 때 이 위에 토대로 빌드. Vite SPA 통한 React 19 경로가 cwkPippa 가 걸은 경로, 이제 본인도 걸을 수 있는 경로.

마무리

스택이 본인 것. 결정도 본인 것. 다음 퀘스트 (뭘 고르든) 가 이제 진짜 토대에서 시작. 가서 뭔가 빌드해.

Code

나란히 — 두 스택의 같은 '리스트 로드' 패턴·tsx
// cwk-site (Next.js) — Server Component, 요청 중 서버에서 돔
// 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() 가진 Client Component
// 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

본인이 갖고 있는 프로젝트 아이디어 (또는 빌드 중인 거) 하나 골라. 위 결정 트리 walk. 각 질문에 정직하게 답. 끝에 Vite SPA vs Next.js 명확한 답 있어야. 이제 적어: (1) 어느 스택 골랐는지, (2) 결정 질문, (3) 빌드 위해 갈 다음 퀘스트 (Vite SPA 면 이거, Next.js 면 next-js-quest, 둘 다 옵션 열어두고 싶으면 둘 다).
Hint
정직한 답이 'cool' 한 답보다 중요. 3명 쓰는 내부 admin 도구에 'RSC 가 미래' 라서 Next.js 픽은 과설계. Public 마케팅 사이트에 '이미 React 알아' 라서 Vite SPA 픽은 under-engineering. 결정 트리가 둘 다의 편향 가르는 게 존재 이유.

Progress

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

댓글 0

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

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