A professional, feature-based Next.js 15 codebase with TypeScript, Tailwind CSS v4, shadcn/ui, and a typed API client.
| Category | Technology |
|---|---|
| Framework | Next.js 16 (App Router, React 19) |
| Language | TypeScript (Strict mode) |
| Styling | Tailwind CSS v4 |
| Components | shadcn/ui (atomic primitives) |
| Icons | Lucide React |
| Validation | Zod |
| Utilities | clsx, tailwind-merge |
Copy the example env file and fill in your values:
cp .env.example .env.localThen edit .env.local with your actual API URL and keys.
Environment file priority (Next.js 15):
| File | When loaded | Committed? |
|---|---|---|
.env |
Always | No |
.env.local |
Local dev (overrides .env) |
No |
.env.development |
npm run dev |
No |
.env.production |
npm run build |
No |
.env.example |
Never (template only) | Yes |
npm installnpm run devOpen http://localhost:3000.
src/
├── app/ # Routes, layouts, server actions (thin pages)
├── components/
│ ├── navbar.tsx # Global navbar
│ ├── footer.tsx # Global footer
│ └── ui/ # Atomic shadcn/ui-style primitives
├── features/ # Feature-based modules
│ ├── auth/ # Authentication domain
│ ├── users/ # Users domain
│ └── shared/ # Cross-cutting: BaseService, schemas
├── hooks/ # Global shared hooks
├── lib/
│ ├── api-client.ts # Typed fetch wrapper
│ └── utils.ts # cn(), shared utilities
├── services/ # Global service layer
├── store/ # Global state management
├── types/ # Shared TypeScript types
├── utils/ # Global pure utilities
└── docs/ # Architecture & usage guides
npm run dev # Start dev server with Turbopack
npm run build # Production build
npm run start # Start production server
npm run lint # ESLint
npm run format # Prettier write
npm run typecheck # TypeScript checkEach feature lives in src/features/<name>/ with its own:
components/— feature-specific UIservices/— API calls and business logictypes/— domain-specific types
See src/docs/api-client-usage.md for full documentation.
// Initialize once in src/lib/api.ts
export const api = initApiClient({
baseUrl: process.env.NEXT_PUBLIC_API_URL ?? "https://api.example.com",
refreshEndpoint: "/auth/refresh",
storage: { /* token storage */ },
});
// Use in Server Components (direct import, no client bundle)
const user = await getUserService().getUserById(id);
// Use in Client Components (extend with client-side storage)
const userService = getUserService().extend({ storage: clientStorage });See .cursorrules for the full project conventions:
- Default to Server Components (
"use client"only when needed) - Arrow-function functional components, PascalCase names
- kebab-case filenames, PascalCase component names
cn()from@/lib/utilsfor conditional className merging- Zod schemas co-located with services