- Follow Next.js Architecture: Use the App Router exclusively with strict React Server Component (RSC) patterns; mark client components with the 'use client' directive only when interactivity or hooks are required; implement route groups with (auth) and (public) conventions for protected routes; use server actions with useFormState/useFormStatus for backend-driven form submissions; configure all environment variables in next.config.mjs with schema validation.
- Follow React Component Patterns: Create components using PascalCase (e.g. UserProfileCard.js, not user-profile-card.js); export all components with named exports (e.g. export function UserCard() { … }); separate presentational and container components using a FeatureContainer/FeatureView pattern; define prop types using PropTypes or JSDoc; implement error boundaries (using libraries like react-error-boundary) for critical UI sections.
- Implement Tailwind CSS Properly: Use Tailwind’s utility classes for styling; use @apply only for complex component abstractions in CSS modules; centralize design tokens (colors, spacing, typography) in tailwind.config.js with semantic names; build responsive designs with mobile-first breakpoint prefixes (e.g. md:, lg:); leverage clsx for conditional class management; avoid arbitrary values by relying on predefined theme scales.
- Integrate Shadcn UI: Install new components with npx shadcn-ui@latest add [component]; extend the theme through a dedicated file (e.g. src/styles/theme.js) using CSS variables; prefer component composition over modifying core styles; implement dark mode using next-themes combined with Shadcn UI’s theming system; never modify core component styles—use the className prop for overrides.
- Use TanStack Query for Data Fetching: Initialize the query client with default options (e.g. staleTime of 5 minutes, retry count of 2); standardize query key generation using key factories; implement global error handling via the QueryClient's onError callback.
- Adopt a Robust Form Handling Strategy: Combine React Hook Form with Zod for schema validation and integrate them with Shadcn UI form components; register every input field properly (using register() or a Controller-like pattern); implement loading states via formState.isSubmitting; integrate form notifications as needed.
- Maintain a Solid Prisma Database Layer: Define your database schema in schema.prisma with strict typing and clear constraints; use a single Prisma Client instance (especially in serverless environments) with efficient connection pooling; implement soft deletes via a deletedAt field pattern; validate query results with runtime validation after operations.
- Follow an Effective State Management Strategy: Use React Context for global UI state (themes, modals, notifications) by creating custom provider components (e.g. using useReducer); for complex, persistent state, consider Zustand; do not mix server state with global state—store server data in the TanStack Query cache.
- Adhere to Ethereum/Solidity Standards: Write upgradeable smart contracts using OpenZeppelin’s Transparent Proxy pattern; target Solidity 0.8.20+ with a strict pragma and optimizations enabled; ensure comprehensive testing with tools like Foundry or Truffle; implement EIP-712 signatures for meta-transactions; use viem or wagmi for type-safe frontend contract interactions.
- Observe General JavaScript Standards: Follow the AirBnB style guide for all JavaScript/JSX code; enforce consistent naming, indentation, use of modern ES6+ features, and strict mode; avoid loosely typed variables by using PropTypes or JSDoc for validation; utilize utility methods (e.g. Pick, Omit, Partial) where applicable.
- Implement Robust Error Handling: Wrap critical UI sections in a global error boundary (integrated with external logging services); adopt a Result pattern for operations, returning objects that indicate success or failure; create custom error classes (e.g. AuthError) for domain-specific issues; use try/catch blocks consistently.
- Optimize Performance Across the Stack: Employ code splitting (using React.lazy and next/dynamic for heavy client components); optimize images using Next.js’s Image component with proper quality/size props; leverage server-side caching strategies (e.g. unstable_cache in Server Components); use memoization (React.memo) to prevent expensive re-renders.
- Jump Straight to Writing Components and Code: Do not include project setup instructions—assume the environment is preconfigured and focus solely on producing clean, modular, and production-ready code.