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
-
Setting up routing with TanStack Router
-
Styling components with MUI v7
-
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 useSuspenseQuery for data fetching
-
Import aliases: @/ , ~types , ~components , ~features
-
Styles: Inline if <100 lines, separate file if >100 lines
-
Use useCallback for event handlers passed to children
-
Default export at bottom
-
No early returns with loading spinners
-
Use useMuiSnackbar for user notifications
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 { apiClient } from '@/lib/apiClient'
~types
src/types
import type { User } from '~types/user'
~components
src/components
import { SuspenseLoader } from '~components/SuspenseLoader'
~features
src/features
import { authApi } from '~features/auth'
Defined in: vite.config.ts lines 180-185
Common Imports Cheatsheet
// React & Lazy Loading import React, { useState, useCallback, useMemo } from "react"; const Heavy = React.lazy(() => import("./Heavy"));
// MUI Components import { Box, Paper, Typography, Button, Grid } from "@mui/material"; import type { SxProps, Theme } from "@mui/material";
// TanStack Query (Suspense) import { useSuspenseQuery, useQueryClient } from "@tanstack/react-query";
// TanStack Router import { createFileRoute } from "@tanstack/react-router";
// Project Components import { SuspenseLoader } from "~components/SuspenseLoader";
// Hooks import { useAuth } from "@/hooks/useAuth"; import { useMuiSnackbar } from "@/hooks/useMuiSnackbar";
// Types import type { Post } from "~types/post";
Topic Guides
🎨 Component Patterns
Modern React components use:
-
React.FC<Props> for type safety
-
React.lazy() for code splitting
-
SuspenseLoader for 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 isLoading checks
-
Type-safe with generics
API Service Layer:
-
Create features/{feature}/api/{feature}Api.ts
-
Use apiClient axios 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
Inline vs Separate:
-
<100 lines: Inline const styles: Record<string, SxProps<Theme>>
100 lines: Separate .styles.ts file
Primary Method:
-
Use sx prop for MUI components
-
Type-safe with SxProps<Theme>
-
Theme access: (theme) => theme.palette.primary.main
MUI v7 Grid:
<Grid size={{ xs: 12, md: 6 }}> // ✅ v7 syntax <Grid xs={12} md={6}> // ❌ Old syntax
📖 Complete Guide: resources/styling-guide.md
🛣️ Routing
TanStack Router - Folder-Based:
-
Directory: routes/my-route/index.tsx
-
Lazy load components
-
Use createFileRoute
-
Breadcrumb data in loader
Example:
import { createFileRoute } from "@tanstack/react-router"; import { lazy } from "react";
const MyPage = lazy(() => import("@/features/my-feature/components/MyPage"));
export const Route = createFileRoute("/my-route/")({ component: MyPage, loader: () => ({ crumb: "My Route" }), });
📖 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 useMuiSnackbar for user feedback
-
NEVER react-toastify
-
TanStack Query onError callbacks
📖 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 any type
-
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
-
useAuth hook 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 @/, ~types, ~components, ~features
-
No Early Returns: Prevents layout shift
-
useMuiSnackbar: 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