DomainScoreCursor Rules
GitHub

1/23/2025

Comprehensive guidelines and best practices for developing React applications using TypeScript, Next.js, and Node.js. Includes coding standards, preferred libraries, file structure, performance optimization, testing requirements, and error handling.



# React (TypeScript, Next.js, Node.js)

# React (TypeScript, Next.js, Node.js) - Best Practices and Guidelines

## Key Principles
- **Write concise, technical responses with accurate TypeScript examples.**
- **Use functional, declarative programming. Avoid classes.**
- **Prefer iteration and modularization over duplication.**
- **Use descriptive variable names with auxiliary verbs (e.g., `isLoading`).**
- **Use lowercase with dashes for directories (e.g., `components/auth-wizard`).**
- **Favor named exports for components.**
- **Use the Receive an Object, Return an Object (RORO) pattern.**

## JavaScript/TypeScript
- **Use `function` keyword for pure functions. Omit semicolons.**
- **Use TypeScript for all code. Prefer interfaces over types. Avoid enums, use maps.**
- **File structure:**
  - Exported component
  - Subcomponents
  - Helpers
  - Static content
  - Types
- **Avoid unnecessary curly braces in conditional statements.**
- **For single-line statements in conditionals, omit curly braces.**
- **Use concise, one-line syntax for simple conditional statements (e.g., `if (condition) doSomething()`).**
- **Prioritize error handling and edge cases:**
  - Handle errors and edge cases at the beginning of functions.
  - Use early returns for error conditions to avoid deeply nested if statements.
  - Place the happy path last in the function for improved readability.
  - Avoid unnecessary else statements; use if-return pattern instead.
  - Use guard clauses to handle preconditions and invalid states early.
  - Implement proper error logging and user-friendly error messages.
  - Consider using custom error types or error factories for consistent error handling.

## Dependencies
- **Next.js 14 App Router**
- **Wagmi v2**
- **Viem v2**

## React/Next.js
- **Use functional components and TypeScript interfaces.**
- **Use declarative JSX.**
- **Use `function`, not `const`, for components.**
- **Use Shadcn UI, Radix, and Tailwind Aria for components and styling.**
- **Implement responsive design with Tailwind CSS.**
- **Use mobile-first approach for responsive design.**
- **Place static content and interfaces at file end.**
- **Use content variables for static content outside render functions.**
- **Minimize `use client`, `useEffect`, and `setState`. Favor RSC.**
- **Use Zod for form validation.**
- **Wrap client components in Suspense with fallback.**
- **Use dynamic loading for non-critical components.**
- **Optimize images:**
  - WebP format
  - Size data
  - Lazy loading
- **Model expected errors as return values:**
  - Avoid using `try/catch` for expected errors in Server Actions.
  - Use `useActionState` to manage these errors and return them to the client.
- **Use error boundaries for unexpected errors:**
  - Implement error boundaries using `error.tsx` and `global-error.tsx` files to handle unexpected errors and provide a fallback UI.
- **Use `useActionState` with `react-hook-form` for form validation.**
- **Code in `services/` dir always throw user-friendly errors that tanStackQuery can catch and show to the user.**
- **Use `next-safe-action` for all server actions:**
  - Implement type-safe server actions with proper validation.
  - Utilize the `action` function from `next-safe-action` for creating actions.
  - Define input schemas using Zod for robust type checking and validation.
  - Handle errors gracefully and return appropriate responses.
  - Use `import type { ActionResponse } from '@/types/actions'`
  - Ensure all server actions return the `ActionResponse` type
  - Implement consistent error handling and success responses using `ActionResponse`
  - Example:
    ```typescript
    'use server'
    import { createSafeActionClient } from 'next-safe-action'
    import { z } from 'zod'
    import type { ActionResponse } from '@/app/actions/actions'
    const schema = z.object({
      value: z.string()
    })
    export const someAction = createSafeActionClient()
      .schema(schema)
      .action(async (input): Promise => {
        try {
          // Action logic here
          return { success: true, data: /* result */ }
        } catch (error) {
          return { success: false, error: error instanceof AppError ? error : appErrors.UNEXPECTED_ERROR, }
        }
      })
    ```

## Key Conventions
1. **Rely on Next.js App Router for state changes.**
2. **Prioritize Web Vitals (LCP, CLS, FID).**
3. **Minimize `use client` usage:**
  - Prefer server components and Next.js SSR features.
  - Use `use client` only for Web API access in small components.
  - Avoid using `use client` for data fetching or state management.

Refer to Next.js documentation for Data Fetching, Rendering, and Routing best practices.