Communitygithub.com

rbikbov/frontend-starter

Старт нового фронтенд-проекта на Next.js (App Router) + TypeScript: фундамент, который закладывается до первой фичи. Использовать, когда нужно: создать проект с нуля; решить, нужны ли Next.js, монорепо, BFF, микрофронтенды; разложить FSD поверх роутинга Next; завести строгий TS, линтер границ, env-конфиг, модель ошибок и API-клиент, тесты, git-хуки, CI, каркас README; навести порядок в молодом проекте после генератора.

What is frontend-starter?

frontend-starter is a Claude Code agent skill that старт нового фронтенд-проекта на Next.js (App Router) + TypeScript: фундамент, который закладывается до первой фичи. Использовать, когда нужно: создать проект с нуля; решить, нужны ли Next.js, монорепо, BFF, микрофронтенды; разложить FSD поверх роутинга Next; завести строгий TS, линтер границ, env-конфиг, модель ошибок и API-клиент, тесты, git-хуки, CI, каркас README; навести порядок в молодом проекте после генератора.

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

Ask in your favorite AI

Open a new chat with this agent skill pre-loaded.

Documentation

Старт проекта на Next.js

Фундамент дешевле всего заложить в первый день: потом каждое правило приходится внедрять поверх кода, который его нарушает. Если есть шаблон frontend-starter — начинай с копии шаблона: в нём шаги ниже уже сделаны и проверены, а этот документ остаётся объяснением решений и чек-листом аудита. Этот документ задаёт порядок шагов и минимальный набор. Как писать сам код — в скилле fsd-frontend (если он есть в проекте), авторизацию — в frontend-auth-session, проверку перед коммитом — в anti-slop-review. Готовые конфиги — в references/configs.md, раскладка Next + FSD с примерами кода — в references/next-structure.md.

Приоритет правил. Явные инструкции пользователя и agent-файлы проекта (AGENTS.md, CLAUDE.md) важнее этого документа. Версии библиотек меняются: перед тем как копировать конфиг, сверь его с документацией установленной версии и не утверждай, что он работает, пока не запустил.

Факты о Next.js — из документации в пакете, а не из этого документа и не из памяти. С 16.2 документация лежит в node_modules/next/dist/docs/, а AGENTS.md проекта на неё ссылается. При расхождении с примерами отсюда права документация установленной версии.

Обозначения: MUST — нарушать нельзя; SHOULD — по умолчанию да, отступление требует причины.


1. Решения до кода

Каждое решение из таблицы записывается в README (раздел «Решения») или в ADR, с причиной. Отступление от значения по умолчанию без записанной причины — не делается.

ВопросПо умолчаниюКогда иначе
Next.js или SPANext.js, если нужен хотя бы один из: SSR/SEO, BFF (секреты, HttpOnly-cookie), route handlersВнутреннее приложение за логином без 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Явное решение «без i18n» записано в README
Пакетный менеджер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. Сразу удалить шаблон генератора: стартовую страницу, SVG из public/, шаблонный README, демо-стили. Заменить README каркасом из references/configs.md. Шаблон, оставленный «на потом», доживает до продакшена. AGENTS.md и CLAUDE.md от create-next-app не удаляются: блок между <!-- BEGIN:nextjs-agent-rules --> и <!-- END:nextjs-agent-rules --> указывает агентам на документацию установленной версии, next dev поддерживает его сам. Свои правила проекта дописываются вне этих маркеров.
  3. Строгий TypeScript (раздел 4 references/configs.md) и скрипт typecheck (tsc --noEmit).
  4. Структура FSD поверх Next (раздел 3 ниже).
  5. Линтер и форматирование: ESLint flat config от eslint-config-next
    • 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, Playwright для e2e (раздел 7).
  11. Git-хуки: husky + lint-staged (eslint --fix, prettier) + commitlint.
  12. CI: lint, typecheck, test, build на каждый push и PR (раздел 8).
  13. Безопасность по умолчанию (раздел 9).
  14. README заполнен тем, что уже правда (раздел 10), и Definition of Done пройден (раздел 11).

Шаги 1–3 — отдельный коммит «scaffold»: так в истории видно, что сделал генератор, а что ты.


3. FSD поверх роутинга Next

По официальному гайду 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) и передача пропсами. Логики в них нет.
  • Route handlers и 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:

  • Ошибки нормализуются в AppError с kind один раз, на границе shared/api (модель — fsd-frontend, references/conventions.md, раздел 1). Выше shared/api никто не разбирает Response, статусы и тексты ошибок.
  • Один request() поверх fetch (или сгенерированный клиент, обёрнутый так же): пробрасывает 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", которое бросает «not implemented», не заводится.


6. Основа UI

  • Токены дизайна — CSS-переменные в :root (и для тёмной темы), подключённые к 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. Логику из них выноси в функции и тестируй unit-тестами, а саму страницу — в e2e.
  • Playwright для 3–10 критических путей. В CI e2e идут против предсказуемого бэкенда (мок-сервер, стенд с тестовой БД), а не против общего стенда, где тесты меняют чужие данные.
  • Первый тест пишется в день ноль: он проверяет, что инфраструктура тестов работает, и задаёт образец.

8. CI

MUST: на каждый push в основную ветку и на каждый PR: lint, typecheck, test, build. Шаблон GitHub Actions — references/configs.md. Для публичных репозиториев Actions бесплатен, для приватных есть месячная квота минут.

  • Сборка в CI идёт на .env.example, без секретов.
  • e2e — отдельной job, когда есть изолированный бэкенд; до тех пор — явная пометка в README, почему их нет в CI.
  • Бейдж CI в README появляется вместе с workflow.

9. Безопасность по умолчанию

  • poweredByHeader: false; заголовки через headers() в next.config.ts: X-Content-Type-Options: nosniff, Referrer-Policy: strict-origin-when-cross-origin, X-Frame-Options: DENY (или frame-ancestors в CSP). CSP с nonce — отдельная задача, но решение «есть / нет и почему» записывается сразу.
  • Server Actions и route handlers — публичные эндпоинты: валидация входа схемой и проверка прав в каждом.
  • dangerouslySetInnerHTML — только с санитайзером и комментарием-причиной.
  • Персональные данные и токены не логируются.
  • Авторизация — по frontend-auth-session.

10. README

Каркас — references/configs.md. Правило одно: в README только то, что правда для кода в этом коммите. Каждый раздел обновляется в том же коммите, что и код, который он описывает. Планы — в отдельном разделе «Дальше», с пометкой, что это не сделано.


11. Definition of Done для старта

  • Шаблон генератора удалён; README — каркас, заполненный правдой.
  • packageManager, engines.node, .nvmrc зафиксированы.
  • TS strict; typecheck, lint, test, build проходят локально (запущены, а не предположены).
  • FSD-раскладка с префиксами _app/_pages; линтер границ ловит импорт вверх.
  • Env через два модуля со схемой; process.env вне них запрещён линтером; .env.example полный.
  • AppError и request() в shared/api, покрыты тестами (сеть, статусы, неверная схема).
  • Провайдеры в _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-токеном, или ревьюишь такой код.

Related Skills