Instructions for AI coding agents working with this Next.js starter template.
This project follows Atomic Design for component organization:
components/
├── atoms/ # Smallest reusable units
│ ├── button/ # Single purpose components
│ └── logos/ # SVG icons and logos
├── molecules/ # Combinations of atoms
│ └── copy-button/ # Button + clipboard functionality
└── organisms/ # Complex feature components
└── card/ # Card layout with multiple elements
Rules:
- Atoms: No dependencies on other components
- Molecules: Combine 2+ atoms, single responsibility
- Organisms: Complex components, can use atoms + molecules
- Each component must have its own folder with index.ts
- Components:
kebab-case.tsx(e.g.,copy-button.tsx) - Tests:
kebab-case.test.tsx(e.g.,copy-button.test.tsx) - Types:
PascalCasefor type names - Files: Lowercase with hyphens
Use absolute imports with @/ prefix:
// ✅ Correct
import Button from "@/components/atoms/button";
import { FCC } from "@/types/react";
// ❌ Wrong
import Button from "../../../components/atoms/button";
import { FCC } from "../../types/react";- Determine atomic level (atom, molecule, or organism)
- Create folder:
src/components/{level}/{component-name}/ - Create files:
{component-name}.tsx- Component implementation{component-name}.test.tsx- Unit testsindex.ts- Exports
- Write types: Props interface with TypeScript strict mode
- Add tests: Cover main functionality
- Use Tailwind: Inline utility classes only
- Create in app directory:
src/app/{route}/page.tsx - Server Component by default: Only add
"use client"if needed - Add metadata: Use Next.js Metadata API
- Add loading state: Create
loading.tsxif async - Add error boundary: Create
error.tsxif needed
- Create route handler:
src/app/api/{endpoint}/route.ts - Export HTTP methods: GET, POST, PUT, DELETE, etc.
- Return NextResponse: Use
NextResponse.json() - Add error handling: Try/catch with proper status codes
- Type request/response: Full TypeScript coverage
- Test all new components
- Test user interactions with
userEvent - Test edge cases and error states
- Mock external dependencies
Test Template:
import { render } from "@testing-library/react";
import { userEvent } from "@testing-library/user-event";
import { describe, test, expect, vi } from "vitest";
describe("ComponentName", () => {
test("should render correctly", () => {
const { getByText } = render(<ComponentName />);
expect(getByText("Expected Text")).toBeDefined();
});
test("should handle user interaction", async () => {
const user = userEvent.setup();
const handler = vi.fn();
const { getByRole } = render(<ComponentName onClick={handler} />);
await user.click(getByRole("button"));
expect(handler).toHaveBeenCalled();
});
});yarn test # Watch mode for development
yarn test:ci # CI mode (runs once)
yarn ts # TypeScript type checkingFollow Conventional Commits:
<type>(<scope>): <subject>
<body>
<footer>
Types:
feat: New featurefix: Bug fixdocs: Documentationstyle: Formatting (not CSS)refactor: Code restructuringtest: Adding testschore: Maintenance
Examples:
feat(auth): add user login functionality
fix(button): resolve click handler race condition
docs(readme): update installation instructions
test(card): add unit tests for card component
chore(deps): update dependencies to latest versions
Automatically runs on git commit:
- Prettier (format code)
- ESLint (lint code)
- TypeScript (type check)
- Vitest (run tests)
If hooks fail:
- Fix the reported issues
- Stage the fixes:
git add . - Try committing again
tsconfig.json- TypeScript with strict mode enabledeslint.config.mjs- ESLint flat config (v9)postcss.config.js- PostCSS for Tailwind CSS 4vitest.config.ts- Vitest test configurationnext.config.js- Next.js configuration.husky/- Git hook scripts
strict: truein tsconfig.json (maintain strict mode)- ESLint flat config structure
- Husky git hooks
- Package manager (must use Yarn)
This project uses Tailwind CSS 4 with the PostCSS plugin.
Configuration:
- Global styles:
src/styles/globals.css - PostCSS setup:
postcss.config.js - Plugins:
@tailwindcss/forms,@tailwindcss/typography
Usage:
// ✅ Inline utility classes
<div className="flex flex-col gap-4 p-6 rounded-lg bg-white dark:bg-gray-900">
<h1 className="text-2xl font-bold text-gray-900 dark:text-white">Title</h1>
<p className="text-gray-600 dark:text-gray-300">Description</p>
</div>
// ❌ Never use CSS Modules
import styles from './component.module.css'; // NOT supported
// ❌ Never use styled-components
const Styled = styled.div``; // NOT in this stackUse Tailwind's dark: variant:
<button className="bg-blue-500 dark:bg-blue-700 text-white">
Button
</button># Production dependency
yarn add package-name
# Development dependency
yarn add -D package-name# Check for updates
yarn outdated
# Update specific package
yarn upgrade package-name@latest
# Update all (carefully)
yarn upgrade-interactive --latestThis project uses Yarn 1.22.22+. Do not use npm or pnpm.
yarn dev # Start dev server at localhost:3000yarn build # Create optimized production build
yarn start # Start production serverThis template is optimized for zero-config Vercel deployment:
- Push to GitHub
- Import project in Vercel
- Deploy automatically
No build configuration needed - Vercel detects Next.js automatically.
- Prefer Server Components: Use Client Components only when needed
- Code splitting: Automatic with Next.js App Router
- Image optimization: Use
next/imagecomponent - Font optimization: Use
next/font - Lazy loading: Use
next/dynamicfor heavy components
Define in src/types/:
// src/types/react.ts
import { ReactNode } from "react";
export type FCC<T = Record<string, unknown>> = {
children: ReactNode;
} & T;Create .env.local:
NEXT_PUBLIC_API_URL=https://api.example.com
SECRET_KEY=your-secret-key
Access in code:
// Client-side (prefix with NEXT_PUBLIC_)
const apiUrl = process.env.NEXT_PUBLIC_API_URL;
// Server-side only
const secret = process.env.SECRET_KEY;- Import errors: Check absolute import paths use
@/ - Type errors: Ensure strict mode compliance
- Tailwind not working: Verify
postcss.config.jsexists - Tests failing: Check
userEvent.setup()is called - Build errors: Run
yarn tsto check types first
yarn build # Test production build
yarn ts # Check TypeScript errors
yarn lint # Check linting errors
yarn test # Run tests in watch mode- Check existing components for patterns
- Review this document and CLAUDE.md
- Check official docs (Next.js, Tailwind, Vitest)
- Ensure all tests pass before committing
- Follow the established patterns in the codebase