cursor.directory

Frontend Architecture

by Elina Lesyk

Frontend Architecture rules and best practices for Cursor

1 rule

# The Ultimate Frontend Development Guide: Principles, Patterns, and Practices ## Development Philosophy - **First Principles**: Embrace SOLID principles, KISS (Keep It Simple, Stupid), and DRY (Don't Repeat Yourself) - **Functional Over Object-Oriented**: Favor functional and declarative programming patterns over imperative and OOP - **Component-Driven Development**: Build applications as compositions of well-defined, reusable components - **Type Safety**: Leverage TypeScript to its fullest potential for enhanced developer experience and code quality - **Think Then Code**: Begin with step-by-step planning and detailed pseudocode before implementation ## Code Architecture & Structure ### Project Organization - Use lowercase with dashes for directories (`components/auth-wizard/`) - Structure files consistently: 1. Exported component/functionality 2. Subcomponents/helpers 3. Static content 4. Types/interfaces ### Naming Conventions - **PascalCase** for: - Components (`UserProfile`) - Type definitions/Interfaces (`UserData`) - **kebab-case** for: - Directory names (`components/auth-wizard/`) - File names (`user-profile.tsx`) - **camelCase** for: - Variables, functions, methods - Hooks, properties, props - **Descriptive Prefixes**: - Prefix event handlers with 'handle': `handleClick`, `handleSubmit` - Prefix boolean variables with verbs: `isLoading`, `hasError`, `canSubmit` - Prefix custom hooks with 'use': `useAuth`, `useForm` ## TypeScript Implementation - Enable strict mode - Prefer interfaces over types for object structures, especially when extending - Use type guards for null/undefined values - Apply generics for type flexibility - Leverage TypeScript utility types (`Partial<>`, `Pick<>`, `Omit<>`) - Avoid enums; use const objects/maps instead - Use discriminated unions for complex state management ## React & Next.js Best Practices ### Component Patterns - Use functional components with explicit TypeScript interfaces - Use the `function` keyword for component definitions, not arrow functions - Extract reusable logic into custom hooks - Place static content in variables outside render functions - Implement proper cleanup in useEffect hooks ### Server Components First - Default to Server Components - Use `'use client'` directive sparingly, only when necessary: - Event listeners - Browser APIs - State that must be client-side - Client-side-only libraries - Use URL query parameters for server state management - Implement proper data fetching using Next.js patterns ### Performance Optimizations - Use React.memo() strategically - Implement useCallback for event handlers passed to child components - Use useMemo for expensive computations - Avoid inline function definitions in JSX - Implement code splitting using dynamic imports - Use proper key props in lists (avoid using index as key) - Wrap client components in Suspense with appropriate fallbacks ## UI and Styling - Use Tailwind CSS for utility-first, maintainable styling - Leverage component libraries like Shadcn UI and Radix UI for accessible, composable UI - Design with mobile-first, responsive principles - Implement dark mode using CSS variables or Tailwind's dark mode features - Maintain consistent spacing values and design tokens - Use Framer Motion library for the animations of components ## Error Handling - The Art of Graceful Failures ### The Early Return Pattern - Handle errors and edge cases at the beginning of functions - Use early returns for error conditions - Place the happy path last in the function - Avoid unnecessary else statements; use if-return pattern instead - Implement guard clauses to handle preconditions ### Structured Error Handling - Use custom error types for consistent error handling - For Next.js Server Actions, model expected errors as return values - Implement error boundaries using error.tsx files - Provide user-friendly error messages - Log errors appropriately for debugging ## Form Validation - Use Zod for schema validation - Implement proper error messages - Use react-hook-form for form state management - Combine with useActionState for server actions ## State Management - Use useState for simple component-level state - Implement useReducer for complex local state - Use React Context for shared state within a component tree - For global state, choose appropriate tools: - Redux Toolkit for complex applications - Zustand for simpler state management - TanStack Query for server state ## Accessibility (a11y) - Use semantic HTML elements - Apply appropriate ARIA attributes only when necessary - Ensure keyboard navigation support - Maintain accessible color contrast ratios - Follow a logical heading hierarchy - Provide clear and accessible error feedback - Test with screen readers
Add rule to Cursor