A batteries-included React 19 + Vite + TypeScript boilerplate for production SPAs — wired with auth scaffolding, typed HTTP client, shadcn/ui primitives, theme, i18n, forms, error boundaries, a11y defaults, and a curated subset of Everything Claude Code (ECC) (11 subagents, 15 slash commands, 11 skills, layered rules, AgentShield, VITE_* secret guard).
Why this exists. Most React starters give you
create-react-app-style scaffolding and stop there. The first week of every new project is spent wiring the same 20 things: auth, routing, theme, forms, error boundaries, i18n, deployment configs, lint hooks, ADRs. This repo does all of that — modern, opinionated, and out of the way — so you can spend day one on product code.
| Layer | Choice | Notes |
|---|---|---|
| Build | Vite 6 + React 19.2 + TypeScript 5 strict | React Compiler enabled; no manual useMemo/useCallback |
| Routing | React Router v7 data router | Lazy routes, <Suspense>, route-level + root error boundaries |
| Server state | TanStack Query v5 + Zod | Schema-validated, typed errors, optimistic updates pattern |
| Client state | Zustand v5 with persist |
Strict boundary — server state never duplicated |
| Styling | Tailwind CSS v4 + shadcn/ui pattern | Tokens in @theme {}; primitives owned in-repo, no CLI |
| Forms | React Hook Form + Zod | Typed <Form> / <FormField> wrappers |
| Auth | Mock JWT + ProtectedRoute + AuthStore | MSW-backed for dev; swap in real provider when ready |
| Theme | Light / dark / system | CSS vars; honors prefers-color-scheme; persists |
| i18n | react-i18next + LanguageDetector | en + vi out of the box, type-safe keys |
| Errors | react-error-boundary + RouteErrorBoundary | Server (5xx) errors surface to boundary; 4xx stay local |
| a11y | jsx-a11y + SkipLink + focus rings | WCAG 2.2 AA targets; /a11y-architect agent |
| Mocks | MSW 2 | Dev-only, tree-shaken from prod bundle |
| Tests | Vitest 2 + Testing Library + Playwright | 80% coverage threshold + E2E |
| Lint / Format | ESLint 9 flat + Prettier + lint-staged + commitlint | Husky hooks, conventional commits |
| Security | AgentShield 1.4 + VITE_* secret guard |
.claude/ audited, prompt-injection scan |
| Deploy | Vercel + Netlify configs | SPA rewrites + security headers + immutable cache |
| CI | GitHub Actions | Lint, type-check, test+coverage, build, security, E2E |
| DX | .editorconfig, .nvmrc, .vscode/, dependabot |
Recommended extensions + workspace settings |
git clone <your-fork-url>
cd react-ecc-starter
bun install # installs deps + sets up Husky hooks
cp .env.example .env.local # fill in VITE_APP_NAME, VITE_API_URL
bun dev # http://localhost:5173Requirements: Bun ≥ 1.3 and Node ≥ 20 (matches .nvmrc).
For Playwright E2E first run: bunx playwright install.
/— landing page with feature grid + Zustand counter demo/contact— RHF + Zod form demo with toast on submit/login— mock auth flow (any credentials work via MSW)/dashboard— protected route showing the signed-in user/posts— MSW-backed CRUD with optimistic updates + rollback- Dark / light / system theme toggle in the header
- EN / VI language toggle
- Root + per-route error boundaries
- Skip-to-content link, focus rings, semantic landmarks
| Command | Purpose |
|---|---|
bun dev |
Vite dev server with HMR (:5173) — MSW auto-starts in dev |
bun run build |
tsc -b && vite build → dist/ |
bun run preview |
Serve dist/ on :4173 |
bun run type-check |
tsc --noEmit |
bun run lint / lint:fix |
ESLint flat config |
bun run test / test:watch / test:coverage |
Vitest (80% threshold) |
bun run test:e2e |
Playwright (run bunx playwright install once first) |
bun run format / format:check |
Prettier on the repo |
bun run security:scan / security:fix |
AgentShield |
src/
├── main.tsx entry — providers + MSW + auth hydration
├── router.tsx React Router v7 routes (lazy + Suspense + errorElement)
├── env.ts typed import.meta.env wrapper with startup validation
├── pages/ route components (home, contact, login, dashboard, posts/*)
├── components/
│ ├── ui/ shadcn-pattern primitives (Button, Card, Dialog, …)
│ ├── layout/ AppLayout + Header + Footer + theme/language toggles
│ ├── theme/ ThemeProvider context
│ ├── auth/ ProtectedRoute + LoginForm
│ ├── posts/ PostList + PostForm + PostCard
│ ├── error/ Root + Route error boundaries
│ └── a11y/ SkipLink
├── hooks/ custom hooks (use-theme, use-auth, use-*-query, …)
├── stores/ Zustand stores (auth, counter)
├── api/ typed API wrappers (auth, posts)
├── lib/ http-client, api-error, query-client, cn, i18n
├── types/ shared types + Zod schemas
├── locales/{en,vi}/ i18n JSON resources
├── mocks/ MSW handlers (dev only, tree-shaken in prod)
└── styles/global.css Tailwind v4 entry + @theme tokens
tests/e2e/ Playwright specs
docs/ architecture, deployment, ADRs, recipes
.claude/ agents, commands, skills, rules, hooks, settings
.github/ workflows, issue/PR templates, dependabot
See docs/architecture.md for the full data flow diagram.
- CLAUDE.md — workflow for Claude Code sessions
- AGENTS.md — full subagent roster + orchestration
- CONTRIBUTING.md — branching, commits, PR workflow
- SECURITY.md — vulnerability reporting + hardening overview
- docs/architecture.md — high-level architecture + data flow
- docs/deployment.md — Vercel / Netlify / Cloudflare / Docker
- docs/adr/ — architecture decisions (React 19, TanStack Query, shadcn pattern, …)
- docs/recipes/ — add-a-page, add-an-endpoint, add-a-primitive
- .claude/README.md — full inventory of agents / commands / skills
Most-used slash commands:
/plan— produce an implementation plan before writing code/tdd— start a Red-Green-Refactor cycle/aside— quick side-question without losing task context/code-review— review the current diff or a PR/a11y-architect— WCAG 2.2 audit on UI changes/security-scan— AgentShield scan/feature-dev— guided feature development flow
Future additions (not in scope today):
- Storybook / Ladle for component documentation
- PWA setup with workbox
- Sentry error tracking integration
- Cloudflare Pages config
- Multi-package monorepo support (pnpm/Turborepo)
- Visual regression testing (Chromatic / Playwright snapshots)
MIT — © Khoi Pham.