Frontend Development Guidelines
Guidelines for building high-quality, maintainable web applications using React (Vite) or Next.js (App Router).
Core Philosophy
- Plan Before Coding: Discuss and understand requirements thoroughly. Assume discussion is needed unless implementation is explicitly requested.
- Stick to Requirements: Do strictly what is asked—nothing more, nothing less. Avoid scope creep and unrequested features.
- Maintain Architecture: Continuously refactor for efficiency and maintainability. Avoid spaghetti code.
- Clarify and Verify: Ask for clarification when scope is unclear. Check if similar features exist before duplicating.
- Clarity and Simplicity: Write understandable code. Avoid unnecessary complexity.
- Consistency: Follow established patterns and conventions.
- User-Centric: Prioritize smooth, intuitive user experiences.
- Efficiency: Make small, verifiable changes over large rewrites.
Code Quality
- Project Structure: Organize by feature or domain
- TypeScript: Use for type safety
- Modularity: Small, focused modules with single responsibility
- Responsiveness: Mobile-first approach by default
Component Architecture
Component Organization
- Componentization: Break UI into small, reusable components
- Atomic Design: Structure as atoms → molecules → organisms → templates → pages
- File per Component: One component per file
- Prevent Duplication: Check for similar components before creating new ones
- Props over Variants: Use props for behavior/content/layout; variants for styling only
- Component Libraries: Use established libraries (e.g., Radix) but customize to fit design system
Component Structure
src/
├── components/ui/ # Reusable components (Button, Input, Card)
└── app/
└── profile/
└── components/ # Feature-specific components (UserProfile)
Rules:
- Truly reusable components →
src/components/ui/ - Feature-specific components → within feature directory
State Management
- Local State: Use
useStateanduseReducerfor component-specific state - Global State: Use
useContextfor shared state (theme, user session) - Modular Organization: Co-locate state logic with related features
Styling and Design
Critical Design System Rules
NEVER write custom, one-off styles in components. All styling must come from a central design system.
- Configuration: Define in
tailwind.config.tsand global CSS (src/index.cssorsrc/globals.css) - Semantic Tokens: Use semantic tokens for colors, gradients, fonts, spacing, shadows
- No Direct Utilities: NEVER use
text-whiteorbg-blackdirectly in components - Theme via Design System: Ensures consistency and easy updates
Design Principles
- Beautiful by Default: Focus on contrast, color, typography, dark/light modes
- Mobile-First: Design for smallest screen first, then scale up
- Purposeful Animations: Subtle, system-defined animations that enhance UX without harming performance
- Accessibility: Semantic HTML, text alternatives, keyboard navigation, proper contrast
Design System Implementation
1. Define Semantic Tokens
Use HSL values for Tailwind color opacity compatibility:
/* index.css */
:root {
/* Colors */
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;
--primary: 210 40% 98%;
--primary-foreground: 210 40% 9.8%;
--primary-glow: 210 40% 88%;
/* Gradients */
--gradient-primary: linear-gradient(135deg, hsl(var(--primary)), hsl(var(--primary-glow)));
--gradient-subtle: linear-gradient(180deg, hsl(var(--background)), hsl(var(--background) / 0.8));
/* Shadows */
--shadow-elegant: 0 10px 30px -10px hsl(var(--primary) / 0.3);
--shadow-glow: 0 0 40px hsl(var(--primary-glow) / 0.4);
/* Animations */
--transition-smooth: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.dark {
--background: 222.2 84% 4.9%;
--foreground: 210 40% 98%;
/* ... dark mode overrides */
}
2. Create Component Variants
Use cva (class-variance-authority) with design system tokens:
// button.tsx
const buttonVariants = cva(
"...",
{
variants: {
variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/90",
// ✅ CORRECT: Use semantic tokens
premium: "bg-gradient-primary text-primary-foreground border-0",
hero: "bg-white/10 text-white border border-white/20 hover:bg-white/20",
}
}
}
)
// Usage:
// ❌ WRONG: <Button className="bg-blue-500 text-white">Click</Button>
// ✅ CORRECT: <Button variant="premium">Click</Button>
Routing
- React (Vite): Client-side routing with
react-router-dom(SPA) - Next.js (App Router): File-system routing with SSR/SSG support
Error Handling
- User Feedback: Toast notifications for operation status
- Error Boundaries: Catch rendering errors, display fallback UI
- Logging: Capture errors and events for debugging
- User-Friendly Messages: Clear, helpful error messages
Performance
- Code Splitting: Use
React.lazyfor dynamic imports (Next.js does this automatically) - Image Optimization: WebP format, lazy loading (use Next.js
<Image>component) - Memoization: Use
React.memo,useMemo,useCallback - Bundle Size: Analyze and remove unused dependencies
Security
- Input Validation: Validate on client and server
- Data Sanitization: Prevent XSS attacks
- Authentication: Secure flows, HttpOnly cookies for tokens
- Dependencies: Keep up-to-date
- Environment Variables: Use
.envfiles, access viaprocess.env, never expose secrets client-side
Documentation
- Component Docs: Document props and usage for shared/complex components
- README: Keep up-to-date with setup, overview, essentials
- API Endpoints: Document endpoints frontend consumes
Common Pitfalls to Avoid
- Premature Coding: Don't code until requirements are clear
- Over-engineering: Don't add unrequested features or anticipate future needs
- Scope Creep: Stay within explicit request boundaries
- Monolithic Files: Create small, focused components
- Direct Styling: Never write styles without tracing back to design system