Frontend Development Guidelines
Purpose
Comprehensive guide for modern React development, emphasizing Suspense-based data fetching, lazy loading, proper file organization, and performance optimization.
When to Use This Skill
- •Creating new components or pages
- •Building new features
- •Fetching data with TanStack Query (React Query)
- •Setting up routing with React Router
- •Styling components with Tailwind CSS and UI component library
- •Implementing dark mode with CSS variables
- •Performance optimization
- •Organizing frontend code
- •TypeScript best practices
Quick Start
New Component Checklist
Creating a component? Follow this checklist:
- • Use
React.FC<Props>pattern with TypeScript - • Lazy load if heavy component:
React.lazy(() => import()) - • Wrap in
<SuspenseLoader>for loading states - • Use
useSuspenseQueryfor data fetching - • Import aliases:
@/(resolves to src/) - • Use UI component library:
@/components/ui - • Style with Tailwind classes and CSS variables for dark mode
- • Use
useCallbackfor event handlers passed to children - • Default export at bottom
- • No early returns with loading spinners
- • Use toast/notification pattern for user feedback
New Feature Checklist
Creating a feature? Set up this structure:
- • Create
features/{feature-name}/directory - • Create subdirectories:
api/,components/,hooks/,helpers/,types/ - • Create API service file:
api/{feature}Api.ts - • Set up TypeScript types in
types/ - • Create route in
routes/{feature-name}/index.tsx - • Lazy load feature components
- • Use Suspense boundaries
- • Export public API from feature
index.ts
Import Aliases Quick Reference
| Alias | Resolves To | Example |
|---|---|---|
@/ | src/ | import { api } from '@/lib/api' |
ActionPhase uses the @/ alias for all imports from the src directory. No other aliases are configured.
Common Imports Cheatsheet
// React & Lazy Loading
import React, { useState, useCallback, useMemo } from 'react';
const Heavy = React.lazy(() => import('./Heavy'));
// UI Components (ActionPhase)
import { Button, Input, Card, CardBody, Badge, Alert, Spinner } from '@/components/ui';
// TanStack Query (React Query - Suspense)
import { useSuspenseQuery, useQueryClient } from '@tanstack/react-query';
// React Router
import { Route, Routes, Navigate, useNavigate, useParams } from 'react-router-dom';
// Project Components
import { SuspenseLoader } from '@/components/SuspenseLoader';
// Auth & Hooks
import { useAuth } from '@/contexts/AuthContext';
import { api } from '@/lib/api';
// Types
import type { Game, Character, Message } from '@/types';
Topic Guides
🎨 Component Patterns
Modern React components use:
- •
React.FC<Props>for type safety - •
React.lazy()for code splitting - •
SuspenseLoaderfor loading states - •Named const + default export pattern
Key Concepts:
- •Lazy load heavy components (DataGrid, charts, editors)
- •Always wrap lazy components in Suspense
- •Use SuspenseLoader component (with fade animation)
- •Component structure: Props → Hooks → Handlers → Render → Export
📖 Complete Guide: resources/component-patterns.md
📊 Data Fetching
PRIMARY PATTERN: useSuspenseQuery
- •Use with Suspense boundaries
- •Cache-first strategy (check grid cache before API)
- •Replaces
isLoadingchecks - •Type-safe with generics
API Service Layer:
- •Create
features/{feature}/api/{feature}Api.ts - •Use
apiClientaxios instance - •Centralized methods per feature
- •Route format:
/form/route(NOT/api/form/route)
📖 Complete Guide: resources/data-fetching.md
📁 File Organization
features/ vs components/:
- •
features/: Domain-specific (posts, comments, auth) - •
components/: Truly reusable (SuspenseLoader, CustomAppBar)
Feature Subdirectories:
features/
my-feature/
api/ # API service layer
components/ # Feature components
hooks/ # Custom hooks
helpers/ # Utility functions
types/ # TypeScript types
📖 Complete Guide: resources/file-organization.md
🎨 Styling
Primary Methods:
- •Use UI Component Library (
@/components/ui) for standard elements - •Use Tailwind CSS for layout and custom styling
- •Use CSS variables for dark mode support
Dark Mode Rules:
// ✅ CORRECT - CSS variables <div className="bg-bg-primary text-text-primary"> // ❌ WRONG - Manual dark classes <div className="bg-white dark:bg-gray-800">
Component Priority:
- •Use UI components when available (Button, Input, Card, etc.)
- •Use Tailwind for layout (flex, grid, spacing)
- •Use CSS variables for colors (always)
📖 Complete Guide: resources/styling-guide.md
🛣️ Routing
React Router - Traditional Setup:
- •Routes defined in
App.tsx - •Protected routes with
AuthContext - •Lazy load pages for code splitting
- •Use
useNavigatefor programmatic navigation
Example:
import { Route, Routes, Navigate } from 'react-router-dom';
import { lazy } from 'react';
const GamePage = lazy(() => import('@/pages/GamePage'));
// In App.tsx
<Routes>
<Route path="/games/:id" element={
<ProtectedRoute>
<GamePage />
</ProtectedRoute>
} />
</Routes>
📖 Complete Guide: resources/routing-guide.md
⏳ Loading & Error States
CRITICAL RULE: No Early Returns
// ❌ NEVER - Causes layout shift
if (isLoading) {
return <LoadingSpinner />;
}
// ✅ ALWAYS - Consistent layout
<SuspenseLoader>
<Content />
</SuspenseLoader>
Why: Prevents Cumulative Layout Shift (CLS), better UX
Error Handling:
- •Use toast notifications or Alert component for user feedback
- •NEVER
react-toastify - •TanStack Query
onErrorcallbacks
📖 Complete Guide: resources/loading-and-error-states.md
⚡ Performance
Optimization Patterns:
- •
useMemo: Expensive computations (filter, sort, map) - •
useCallback: Event handlers passed to children - •
React.memo: Expensive components - •Debounced search (300-500ms)
- •Memory leak prevention (cleanup in useEffect)
📖 Complete Guide: resources/performance.md
📘 TypeScript
Standards:
- •Strict mode, no
anytype - •Explicit return types on functions
- •Type imports:
import type { User } from '~types/user' - •Component prop interfaces with JSDoc
📖 Complete Guide: resources/typescript-standards.md
🔧 Common Patterns
Covered Topics:
- •React Hook Form with Zod validation
- •DataGrid wrapper contracts
- •Dialog component standards
- •
useAuthhook for current user - •Mutation patterns with cache invalidation
📖 Complete Guide: resources/common-patterns.md
📚 Complete Examples
Full working examples:
- •Modern component with all patterns
- •Complete feature structure
- •API service layer
- •Route with lazy loading
- •Suspense + useSuspenseQuery
- •Form with validation
📖 Complete Guide: resources/complete-examples.md
Navigation Guide
| Need to... | Read this resource |
|---|---|
| Create a component | component-patterns.md |
| Fetch data | data-fetching.md |
| Organize files/folders | file-organization.md |
| Style components | styling-guide.md |
| Set up routing | routing-guide.md |
| Handle loading/errors | loading-and-error-states.md |
| Optimize performance | performance.md |
| TypeScript types | typescript-standards.md |
| Forms/Auth/DataGrid | common-patterns.md |
| See full examples | complete-examples.md |
Core Principles
- •Lazy Load Everything Heavy: Routes, DataGrid, charts, editors
- •Suspense for Loading: Use SuspenseLoader, not early returns
- •useSuspenseQuery: Primary data fetching pattern for new code
- •Features are Organized: api/, components/, hooks/, helpers/ subdirs
- •Styles Based on Size: <100 inline, >100 separate
- •Import Aliases: Use @/ for all src/ imports
- •No Early Returns: Prevents layout shift
- •Toast/Alert: For all user notifications
Quick Reference: File Structure
src/
features/
my-feature/
api/
myFeatureApi.ts # API service
components/
MyFeature.tsx # Main component
SubComponent.tsx # Related components
hooks/
useMyFeature.ts # Custom hooks
useSuspenseMyFeature.ts # Suspense hooks
helpers/
myFeatureHelpers.ts # Utilities
types/
index.ts # TypeScript types
index.ts # Public exports
components/
SuspenseLoader/
SuspenseLoader.tsx # Reusable loader
CustomAppBar/
CustomAppBar.tsx # Reusable app bar
routes/
my-route/
index.tsx # Route component
create/
index.tsx # Nested route
Modern Component Template (Quick Copy)
import React, { useState, useCallback } from 'react';
import { Box, Paper } from '@mui/material';
import { useSuspenseQuery } from '@tanstack/react-query';
import { featureApi } from '../api/featureApi';
import type { FeatureData } from '~types/feature';
interface MyComponentProps {
id: number;
onAction?: () => void;
}
export const MyComponent: React.FC<MyComponentProps> = ({ id, onAction }) => {
const [state, setState] = useState<string>('');
const { data } = useSuspenseQuery({
queryKey: ['feature', id],
queryFn: () => featureApi.getFeature(id),
});
const handleAction = useCallback(() => {
setState('updated');
onAction?.();
}, [onAction]);
return (
<Box sx={{ p: 2 }}>
<Paper sx={{ p: 3 }}>
{/* Content */}
</Paper>
</Box>
);
};
export default MyComponent;
For complete examples, see resources/complete-examples.md
Related Skills
- •error-tracking: Error tracking with Sentry (applies to frontend too)
- •backend-dev-guidelines: Backend API patterns that frontend consumes
Skill Status: Modular structure with progressive loading for optimal context management