A modern, opinionated Next.js starter with a production-ready foundation.
| Tool | Version |
|---|---|
| Next.js | 16 (App Router, Turbopack) |
| React | 19 |
| TypeScript | 5 |
| Tailwind CSS | 4 |
| shadcn/ui | latest (new-york) |
| Zod | 4 |
| Vitest | 4 |
| Playwright | 1 |
- App Router — File-based routing with layouts, loading states, and error boundaries
- Turbopack — Default bundler for dev and production (2–5× faster builds, up to 10× faster Fast Refresh)
- React Compiler — Stable opt-in support for automatic memoization via
reactCompiler: true - Cache Components — Explicit opt-in caching with
"use cache"directive and Partial Pre-Rendering - Type-safe env vars — Validated at build time via
@t3-oss/env-nextjs+ Zod - Dark mode — System-aware theme switching with
next-themes - UI components — Accessible primitives via shadcn/ui + Radix UI
- Toast notifications — Sonner with dark mode support
- Code quality — ESLint (flat config) + Prettier with Tailwind class sorting
- Git hooks — Husky + lint-staged + commitlint (Conventional Commits)
- Testing — Unit tests with Vitest + RTL + MSW, E2E with Playwright
- CI — GitHub Actions: lint, format, unit tests, build, E2E tests
# Install dependencies
pnpm install
# Copy environment variables
cp .env.example .env
# Start development server
pnpm devOpen http://localhost:3000.
pnpm dev # Start development server (Turbopack)
pnpm build # Build for production
pnpm start # Start production server
pnpm lint # Run ESLint
pnpm format # Format with Prettier
pnpm format:check # Check formatting without writingpnpm test # Run unit tests (Vitest)
pnpm test:watch # Unit tests in watch mode
pnpm test:ui # Unit tests with visual UI
pnpm test:coverage # Coverage report# First time only — install browser
pnpm exec playwright install chromium
pnpm test:e2e # Run E2E tests (Playwright)
pnpm test:e2e:ui # E2E with visual debugger
pnpm test:e2e:report # Open last HTML reportsrc/
├── app/ # App Router pages and layouts
│ ├── (app)/ # Main route group
│ ├── error.tsx # Error boundary (500)
│ ├── not-found.tsx # 404 page
│ ├── loading.tsx # Loading state
│ ├── layout.tsx # Root layout
│ └── providers.tsx # Client-side providers
├── components/
│ ├── layout/ # Layout primitives
│ └── shadcn-ui/ # shadcn/ui components
├── lib/
│ └── utils/cn.ts # cn() helper (clsx + tailwind-merge)
├── providers/
│ └── theme-provider.tsx # next-themes wrapper
├── styles/
│ ├── globals.css # Tailwind + shadcn theme tokens
│ └── fonts.ts # Inter + JetBrains Mono via next/font
├── test/
│ ├── mocks/
│ │ ├── handlers.ts # MSW handlers (shared across tests)
│ │ └── server.ts # MSW Node server
│ └── utils/
│ └── render.tsx # Custom render with app providers
└── env.ts # Type-safe env vars (server + client)
e2e/
├── pages/ # Page Objects (one file per page)
└── *.spec.ts # Playwright test specs
Variables are validated at build time. Add new ones to src/env.ts:
server— server-only variablesclient— public variables (NEXT_PUBLIC_*)
Always import env from @/env instead of using process.env directly.
# .env.example
NEXT_PUBLIC_APP_URL=http://localhost:3000This project uses shadcn/ui with the new-york style. Add components with:
pnpm dlx shadcn add <component>Components are installed into src/components/shadcn-ui/.
MIT