Communitygithub.com

rbikbov/frontend-starter

새로운 Next.js (App Router) + TypeScript 프론트엔드 프로젝트의 시작: 첫 기능이 추가되기 전에 다져야 할 기초. 다음과 같은 경우에 사용: 프로젝트를 처음부터 생성; Next.js, 모노레포, BFF, 마이크로프론트엔드가 필요한지 결정; Next 라우팅 위에 FSD 배치; 엄격한 TS, 경계 린터, env 설정, 에러 모델과 API 클라이언트, 테스트, git 훅, CI, README 골격 도입; 생성기로 만든 프로젝트를 정리.

frontend-starter란 무엇인가요?

`rbikbov/frontend-starter` 스킬은 Next.js (App Router) + TypeScript 기반의 새 프론트엔드 프로젝트를 시작할 때 반드시 거쳐야 할 기초 공사 단계를 안내합니다. 이 스킬은 프로젝트 생성, 기술 선택(Next.js vs SPA, 모노레포 등), FSD(Feature-Sliced Design) 아키텍처 적용, 엄격한 TypeScript 설정, 경계 린터, env 설정, 에러 모델 및 API 클라이언트 구축, 테스트(Vitest, Playwright), git 훅, CI, README 템플릿까지 모든 초기 설정을 체계적으로 다룹니다. 특히 Next 공식 문서(`node_modules/next/dist/docs/`)를 최우선 참조하며, 사용자 명령과 `AGENTS.md`, `CLAUDE.md`가 이 문서보다 우선합니다. 모든 결정은 README에 이유와 함께 기록되어야 하며, '나중에 필요할 때' 추가하는 원칙을 강조합니다. Claude Code, Cursor, Codex와 같은 AI 에이전트 환경에서 사용하기 적합하며, 프로젝트의 초기 품질을 보장하고 기술 부채를 최소화합니다.

지원 대상✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/rbikbov/frontend-starter/tree/HEAD/.claude/skills/frontend-bootstrap

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

Next.js 프로젝트 시작하기

기초는 첫날에 다지는 것이 가장 싸게 먹힙니다. 나중에 모든 규칙을 이미 위반한 코드 위에 억지로 끼워 넣어야 하거든요. frontend-starter 템플릿이 있다면 템플릿 복사본으로 시작하세요: 템플릿에는 아래 단계가 이미 완료되고 검증되어 있으며, 이 문서는 결정에 대한 설명과 감사 체크리스트 역할을 합니다. 이 문서는 단계 순서와 최소 필수 항목을 정의합니다. 실제 코드 작성은 fsd-frontend 스킬(프로젝트에 있다면), 인증은 frontend-auth-session, 커밋 전 검사는 anti-slop-review 스킬을 참고하세요. 완성된 설정은 references/configs.md에, Next + FSD 구조와 코드 예제는 references/next-structure.md에 있습니다.

규칙 우선순위. 사용자의 명시적 지시와 프로젝트의 에이전트 파일(AGENTS.md, CLAUDE.md)이 이 문서보다 중요합니다. 라이브러리 버전은 변하므로, 설정을 복사하기 전에 설치된 버전의 문서와 대조하고 직접 실행해보기 전까지는 작동한다고 단정하지 마세요.

Next.js에 대한 사실은 이 문서나 기억이 아닌 패키지 내 문서에서 가져옵니다. 16.2부터 문서는 node_modules/next/dist/docs/에 있으며, 프로젝트의 AGENTS.md가 이를 참조합니다. 여기 예제와 차이가 있다면 설치된 버전의 문서가 옳습니다.

표기: MUST — 위반 불가; SHOULD — 기본적으로 예, 예외에는 이유가 필요함.


1. 코드 작성 전 결정

표의 각 결정은 README(‘결정’ 섹션) 또는 ADR에 이유와 함께 기록합니다. 이유 없이 기본값에서 벗어나는 것은 금지됩니다.

질문기본값다른 경우
Next.js 또는 SPASSR/SEO, BFF(비밀, HttpOnly 쿠키), route handler 중 하나라도 필요하면 Next.js로그인이 필요하고 SEO와 BFF가 필요 없는 내부 앱 → Vite + React Router: 빌드와 배포가 더 간단함
라우터App RouterPages Router — 기존 프로젝트에서만
모노레포아니오, 단일 앱두 번째 앱이나 패키지가 실제로 생기면 → pnpm workspaces; Nx/Turborepo — 빌드나 CI가 느려지기 시작할 때
Multi-Zones, 마이크로프론트엔드아니오독립적인 팀이 독립적으로 릴리스할 때
서버 데이터초기 로딩은 Server Components; 인터랙티브 클라이언트 데이터와 뮤테이션은 TanStack Query순수 클라이언트 앱 → TanStack Query만
텍스트 및 i18n첫날부터 번역 모듈(next-intl 또는 유사), 단일 로케일이라도 프로젝트가 fsd-frontend를 따르면README에 ‘i18n 없음’ 명시적 결정 기록
패키지 매니저pnpm, packageManager에 버전 명시—
배포즉시 결정: Vercel, Node 서버(output: "standalone") 또는 Docker이에 따라 env, 캐시, CI가 달라짐

MUST: ‘미래를 위해’ 기술을 미리 추가하지 마세요. 모노레포, 두 번째 라우터, Storybook, 상태 관리자, MSW(‘백엔드 대용’)는 첫 번째 실제 사용자가 생길 때 추가합니다.


2. 단계 순서

  1. 프로젝트 생성 (pnpm create next-app@latest): TypeScript, ESLint, Tailwind, App Router. packageManager, engines.node(Next 16은 Node 20.9+ 필요) 및 .nvmrc 고정.
  2. 생성기 템플릿 즉시 삭제: 시작 페이지, public/의 SVG, 템플릿 README, 데모 스타일. README를 references/configs.md의 골격으로 대체. ‘나중에’ 남겨둔 템플릿은 프로덕션까지 살아남음. create-next-app의 AGENTS.md와 CLAUDE.md는 삭제하지 마세요: <!-- BEGIN:nextjs-agent-rules -->와 <!-- END:nextjs-agent-rules --> 사이 블록이 설치된 버전의 문서를 에이전트가 참조하도록 하며, next dev가 이를 자동으로 유지합니다. 프로젝트 자체 규칙은 이 마커 바깥에 추가합니다.
  3. 엄격한 TypeScript (references/configs.md의 4절) 및 typecheck 스크립트 (tsc --noEmit).
  4. Next 위의 FSD 구조 (아래 3절).
  5. 린터 및 포매팅: eslint-config-next 기반 ESLint flat config + type-aware 규칙 + 경계 린터 + Prettier. Next 16은 next lint를 제거했고 next build 시 린트하지 않음 — 린터는 별도 스크립트와 CI에서 실행.
  6. Env 설정 (4절).
  7. 에러 모델 및 API 클라이언트를 shared/api에 (5절).
  8. 프로바이더를 _app 계층에: QueryClient, 테마, i18n, 전역 서비스(toast, confirm)는 shared의 포트 + _app에서 구현.
  9. UI 기초 (6절).
  10. 테스트: Vitest + Testing Library + MSW, e2e는 Playwright (7절).
  11. Git 훅: husky + lint-staged (eslint --fix, prettier) + commitlint.
  12. CI: 모든 푸시와 PR에 lint, typecheck, test, build (8절).
  13. 기본 보안 (9절).
  14. README를 이미 사실인 내용으로 채우고 (10절), 완료 조건(Definition of Done) 통과 (11절).

1~3단계는 별도 커밋 ‘scaffold’로: 생성기가 한 일과 당신이 한 일을 기록에서 구분할 수 있습니다.


3. Next 라우팅 위의 FSD

공식 FSD 가이드(App Router)에 따라: Next의 서비스 폴더 app/은 프로젝트 루트에, FSD 계층은 src/에, app과 pages 계층은 Next 서비스 폴더와 혼동을 피하기 위해 _ 접두사를 붙입니다.

app/                         Next 라우팅: 경로 파일만
├── layout.tsx               루트 레이아웃 → src/_app의 프로바이더
├── (auth)/sign-in/page.tsx  export { SignInPage as default } from "@/_pages/sign-in"
└── api/auth/login/route.ts  route handler (BFF), 얇게
proxy.ts                     Next 16+ (이전에는 middleware.ts), app/ 옆에
src/
├── _app/                    app 계층: 프로바이더, 전역 스타일, 서비스 구현
├── _pages/                  pages 계층
├── widgets/                 (프로젝트에서 사용하는 경우)
├── features/
├── entities/
└── shared/{ui,api,lib,config}

MUST:

  • app/의 파일은 얇게: src/_pages에서 페이지를 다시 내보내기, generateMetadata, params/searchParams 파싱(Next 15+에서는 Promise이므로 await 필요) 및 props 전달만. 로직 없음.
  • Route handler와 Server Actions는 얇게: 입력을 파싱하고 검증 → src의 함수 호출 → 응답 반환. 각각은 공개 진입점이므로 스스로 인증을 확인하며 proxy.ts에 의존하지 않음.
  • src/app과 src/pages를 생성하지 마세요: Next는 루트와 src 모두에서 서비스 폴더를 찾으며, 같은 이름의 폴더가 쉽게 두 번째 라우터가 될 수 있습니다.
  • 경계 린터는 접두사를 인식: src/app, src/pages/* 대신 src/_app, src/_pages/* 패턴 (설정은 fsd-frontend, references/conventions.md, 11절).
  • "use client"는 트리에서 가능한 한 아래에 배치. 페이지는 기본적으로 서버 컴포넌트, 클라이언트 컴포넌트는 인터랙션이 있는 리프 노드.
  • 비밀 모듈은 import "server-only"로 시작, window를 사용하는 모듈은 import "client-only"로 시작.

자세한 내용과 코드: references/next-structure.md.


4. 환경 설정

MUST:

  • 변수는 두 모듈에서 읽음: shared/config/env.server.ts (import "server-only") 및 shared/config/env.client.ts. 스키마는 zod, 임포트 시 검증: 설정 오류는 첫 번째 요청이 아닌 시작 시점에 발생. 나머지 코드에서는 process.env 사용 금지 (린터 규칙).
  • NEXT_PUBLIC_*는 빌드 시 번들에 포함되며 process.env.NEXT_PUBLIC_X 직접 접근 시에만: 구조 분해나 process.env[name] 사용 금지. 여러 환경에 다른 공개 값을 가진 단일 이미지는 이렇게 빌드할 수 없음 — 해당 값은 서버에서 읽어 아래로 전달.
  • 비밀 값은 절대 NEXT_PUBLIC_ 접두사 없음.
  • .env.example은 모든 변수에 주석과 안전한 값을 포함; .env*는 .gitignore에, .env.example은 제외. CI 빌드는 .env.example의 값으로 통과.

5. 에러 모델 및 API 클라이언트

MUST:

  • 에러는 shared/api 경계에서 한 번 kind를 가진 AppError로 정규화 (모델은 fsd-frontend, references/conventions.md, 1절). shared/api 위에서는 아무도 Response, 상태 코드, 에러 텍스트를 직접 분석하지 않음.
  • fetch 기반의 단일 request() (또는 동일하게 래핑된 생성 클라이언트): signal 전달, 네트워크 에러를 network로 변환, HTTP 상태를 kind로 변환, 응답 본문을 스키마로 검증. 예: references/next-structure.md.
  • 에러 유형은 코드 기반: 상태, extensions.code (GraphQL은 200으로 에러 응답), 본문의 code. 백엔드가 텍스트만 반환하면 단일 매퍼에서 텍스트 매핑, 이유 주석 및 테스트 포함.
  • 백엔드 응답은 경계에서 도메인 타입으로 매핑; DTO는 UI로 전달되지 않음.
  • 사용자 데이터는 사용자 간 캐시되지 않음: 세션에 의존하는 응답에 "use cache"/unstable_cache 사용 금지.
  • 스키마(OpenAPI, GraphQL)가 있으면 클라이언트는 스키마에서 생성. 스키마 또는 생성된 코드는 리포지토리에 포함: CI가 실제 백엔드에 접근하지 않아야 함.

SHOULD: 전송 계층 위의 인터페이스(AuthApi + 팩토리) — 두 번째 소비자가 생겼을 때만 (fsd-frontend, references/state-and-data.md, 2.1). type: "mock" 같은 설정 값으로 ‘구현되지 않음’을 던지는 것은 도입하지 않음.


6. UI 기초

  • 디자인 토큰 — :root(및 다크 테마용)의 CSS 변수, Tailwind v4에 @theme로 연결. 컴포넌트에서는 토큰만 사용; 원시 HEX 및 임의 값(text-[#3a3a3a])은 주석과 함께 일회성 예외.
  • 클래스가 존재해야 함. shadcn/ui 및 예제에서 복사한 컴포넌트는 자체 토큰(bg-card, text-muted-foreground)과 함께 제공됨. 해당 토큰을 정의하거나 클래스를 교체하세요 — 그렇지 않으면 컴포넌트가 조용히 스타일 없이 남음.
  • shared/ui의 기본 컴포넌트는 접근성을 위해 headless 라이브러리(Radix, React Aria) 기반; 변형은 cva, 클래스 병합은 cn (clsx + tailwind-merge).
  • 폰트는 next/font, 이미지는 크기를 명시한 next/image, images.remotePatterns는 명시적으로 나열.
  • Storybook — UI 키트가 여러 앱이나 팀에서 재사용될 때, 그 이전에는 도입하지 않음.

7. 테스트

  • Vitest + Testing Library + jsdom + MSW (onUnhandledFrame: "error" (MSW 3; MSW 2에서는 onUnhandledRequest)). 설정: references/configs.md.
  • Vitest는 async Server Components를 렌더링할 수 없음. 로직은 함수로 추출하여 단위 테스트로 테스트하고, 페이지 자체는 e2e로 테스트.
  • Playwright — 3~10개의 중요 경로에 대해. CI의 e2e는 예측 가능한 백엔드(모크 서버, 테스트 DB가 있는 스탠드)를 대상으로 하며, 테스트가 다른 사람의 데이터를 변경하는 공용 스탠드는 대상으로 하지 않음.
  • 첫 번째 테스트는 0일차에 작성: 테스트 인프라가 작동하는지 확인하고 샘플을 제공.

8. CI

MUST: 메인 브랜치에 푸시할 때마다, 모든 PR에 대해: lint, typecheck, test, build. GitHub Actions 템플릿은 references/configs.md. 공개 리포지토리에는 Actions 무료, 비공개에는 월별 분량 제한.

  • CI 빌드는 .env.example로 진행, 비밀 값 없이.
  • e2e는 격리된 백엔드가 있을 때 별도 job으로; 그 전까지는 README에 CI에 e2e가 없는 이유를 명시적으로 표시.
  • CI 배지는 workflow와 함께 README에 추가.

9. 기본 보안

  • poweredByHeader: false; next.config.ts의 headers()를 통한 헤더: X-Content-Type-Options: nosniff, Referrer-Policy: strict-origin-when-cross-origin, X-Frame-Options: DENY (또는 CSP의 frame-ancestors). CSP with nonce는 별도 작업이지만, ‘있음/없음 및 이유’ 결정은 즉시 기록.
  • Server Actions와 route handlers는 공개 엔드포인트: 스키마로 입력 검증, 각각에서 권한 확인.
  • dangerouslySetInnerHTML — sanitizer와 이유 주석이 있는 경우에만.
  • 개인 데이터와 토큰은 로깅하지 않음.
  • 인증은 frontend-auth-session 참조.

10. README

골격: references/configs.md. 규칙 하나: README에는 이 커밋의 코드에 실제로 해당하는 내용만. 각 섹션은 설명하는 코드와 같은 커밋에서 업데이트. 계획은 별도 ‘다음 단계’ 섹션에, 아직 완료되지 않았음을 표시.


11. 시작 완료 조건 (Definition of Done)

  • 생성기 템플릿 삭제됨; README는 실제 내용으로 채워진 골격.
  • packageManager, engines.node, .nvmrc 고정.
  • TS strict; typecheck, lint, test, build 로컬에서 통과 (실제 실행, 추정 아님).
  • _app/_pages 접두사를 사용한 FSD 구조; 경계 린터가 상위 계층 임포트 감지.
  • Env는 스키마가 있는 두 모듈로; process.env 외부 사용은 린터가 금지; .env.example 완전함.
  • shared/api에 AppError 및 request() 구현, 테스트로 커버 (네트워크, 상태, 잘못된 스키마).
  • _app의 프로바이더; 서버에서 QueryClient는 사용자 간 공유되지 않음.
  • 디자인 토큰은 CSS 변수로; 사용된 모든 클래스가 존재.
  • Vitest + MSW + Playwright 설정, 각각 하나의 실제 테스트.
  • Git 훅과 commitlint 작동.
  • CI 통과.
  • 보안 헤더 및 poweredByHeader: false.
  • 1절의 결정 사항 기록됨.

12. 의심될 때

  • ‘지금 추가’와 ‘필요할 때 추가’ 사이에서 → 필요할 때.
  • ‘직접 설정’과 ‘create-next-app이 생성한 대로 유지’ 사이에서 → 변경할 이유가 생길 때까지 유지하고, 변경 시 이유 기록.
  • ‘단일 앱’과 ‘모노레포’ 사이에서 → 단일 앱.
  • ‘기억 속 설정’과 ‘현재 버전 문서의 설정’ 사이에서 → 문서.

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

rbikbov/frontend-starter

Creates Architecture Decision Records documenting key technical decisions with context, alternatives considered, tradeoffs, consequences, and decision owners. Use when documenting "architecture decisions", "technical choices", "design decisions", or "ADRs".

rbikbov/frontend-starter

Проверка фронтенд-кода и документации на «нейрослоп» перед коммитом, PR или публикацией репозитория: остатки генераторов, мёртвые и недоделанные опции, утверждения в README и комментариях, не подтверждённые кодом, маркетинговый тон и эмодзи, лишние абстракции, хрупкая обработка ошибок, персональные данные в логах, несуществующие классы стилей. Использовать, когда просят проверить код или репозиторий «на слоп», подготовить проект к публикации или показу, сделать ревью кода, написанного с помощью ИИ, или перед тем как закоммитить собственную большую правку.

rbikbov/frontend-starter

Процесс разработки фичи с агентом: PRD с Non-Goals → компактная спецификация → задачи по одной на коммит → read-only исследование → tracer bullet → сборка с тестом сначала → независимое ревью субагентом → проверка в браузере. Использовать, когда просят сделать фичу, экран, пользовательский сценарий или заметное изменение поведения; когда нужно написать PRD, спецификацию или разбить работу на задачи; когда работа больше одного коммита. Не использовать для опечаток и однострочных правок.

rbikbov/frontend-starter

Авторизация и сессия во фронтенде на Next.js (App Router): где хранить токены, BFF на route handlers с HttpOnly-cookie, refresh токена без гонок, определение «не авторизован» (включая GraphQL, который отвечает 200), проверки в proxy.ts и Data Access Layer, безопасный редирект после входа, выход без утечки данных прошлого пользователя, токены в ссылках сброса пароля, формы входа и восстановления. Использовать, когда проектируешь или пишешь вход, регистрацию, восстановление пароля, защищённые страницы, API-клиент с refresh-токеном, или ревьюишь такой код.

관련 스킬