frontend-patterns — ai-agents frontend-patterns, everything-claude-code, official, ai-agents, ide skills, anthropic, claude-code, developer-tools, Claude Code, Cursor, Windsurf

Verified
v1.0.0
GitHub

About this Skill

Perfect for Frontend Agents needing advanced React component composition and state management capabilities. Frontend development patterns for React, Next.js, state management, performance optimization, and UI best practices.

# Core Topics

affaan-m affaan-m
[116.8k]
[15188]
Updated: 3/30/2026

Agent Capability Analysis

The frontend-patterns skill by affaan-m is an open-source official AI agent skill for Claude Code and other IDE workflows, helping agents execute tasks with better context, repeatability, and domain-specific guidance. Optimized for ai-agents, anthropic, claude-code.

Ideal Agent Persona

Perfect for Frontend Agents needing advanced React component composition and state management capabilities.

Core Value

Empowers agents to optimize React applications using composition over inheritance, compound components, and render props patterns, while leveraging libraries like React Query and SWR for data fetching and performance optimization.

Capabilities Granted for frontend-patterns

Implementing accessible and responsive UI patterns for React applications
Optimizing performance using memoization, virtualization, and code splitting techniques
Managing state with useState, useReducer, and Zustand for complex frontend logic

! Prerequisites & Limits

  • Requires React or Next.js project setup
  • Familiarity with JavaScript and TypeScript necessary
  • Limited to frontend development, not applicable to backend or full-stack development
Labs Demo

Browser Sandbox Environment

⚡️ Ready to unleash?

Experience this Agent in a zero-setup browser environment powered by WebContainers. No installation required.

Boot Container Sandbox

frontend-patterns

Install frontend-patterns, an AI agent skill for AI agent workflows and automation. Works with Claude Code, Cursor, and Windsurf with one-command setup.

SKILL.md
Readonly

Frontend Development Patterns

Modern frontend patterns for React, Next.js, and performant user interfaces.

When to Activate

  • Building React components (composition, props, rendering)
  • Managing state (useState, useReducer, Zustand, Context)
  • Implementing data fetching (SWR, React Query, server components)
  • Optimizing performance (memoization, virtualization, code splitting)
  • Working with forms (validation, controlled inputs, Zod schemas)
  • Handling client-side routing and navigation
  • Building accessible, responsive UI patterns

Component Patterns

Composition Over Inheritance

typescript
1// PASS: GOOD: Component composition 2interface CardProps { 3 children: React.ReactNode 4 variant?: 'default' | 'outlined' 5} 6 7export function Card({ children, variant = 'default' }: CardProps) { 8 return <div className={`card card-${variant}`}>{children}</div> 9} 10 11export function CardHeader({ children }: { children: React.ReactNode }) { 12 return <div className="card-header">{children}</div> 13} 14 15export function CardBody({ children }: { children: React.ReactNode }) { 16 return <div className="card-body">{children}</div> 17} 18 19// Usage 20<Card> 21 <CardHeader>Title</CardHeader> 22 <CardBody>Content</CardBody> 23</Card>

Compound Components

typescript
1interface TabsContextValue { 2 activeTab: string 3 setActiveTab: (tab: string) => void 4} 5 6const TabsContext = createContext<TabsContextValue | undefined>(undefined) 7 8export function Tabs({ children, defaultTab }: { 9 children: React.ReactNode 10 defaultTab: string 11}) { 12 const [activeTab, setActiveTab] = useState(defaultTab) 13 14 return ( 15 <TabsContext.Provider value={{ activeTab, setActiveTab }}> 16 {children} 17 </TabsContext.Provider> 18 ) 19} 20 21export function TabList({ children }: { children: React.ReactNode }) { 22 return <div className="tab-list">{children}</div> 23} 24 25export function Tab({ id, children }: { id: string, children: React.ReactNode }) { 26 const context = useContext(TabsContext) 27 if (!context) throw new Error('Tab must be used within Tabs') 28 29 return ( 30 <button 31 className={context.activeTab === id ? 'active' : ''} 32 onClick={() => context.setActiveTab(id)} 33 > 34 {children} 35 </button> 36 ) 37} 38 39// Usage 40<Tabs defaultTab="overview"> 41 <TabList> 42 <Tab id="overview">Overview</Tab> 43 <Tab id="details">Details</Tab> 44 </TabList> 45</Tabs>

Render Props Pattern

typescript
1interface DataLoaderProps<T> { 2 url: string 3 children: (data: T | null, loading: boolean, error: Error | null) => React.ReactNode 4} 5 6export function DataLoader<T>({ url, children }: DataLoaderProps<T>) { 7 const [data, setData] = useState<T | null>(null) 8 const [loading, setLoading] = useState(true) 9 const [error, setError] = useState<Error | null>(null) 10 11 useEffect(() => { 12 fetch(url) 13 .then(res => res.json()) 14 .then(setData) 15 .catch(setError) 16 .finally(() => setLoading(false)) 17 }, [url]) 18 19 return <>{children(data, loading, error)}</> 20} 21 22// Usage 23<DataLoader<Market[]> url="/api/markets"> 24 {(markets, loading, error) => { 25 if (loading) return <Spinner /> 26 if (error) return <Error error={error} /> 27 return <MarketList markets={markets!} /> 28 }} 29</DataLoader>

Custom Hooks Patterns

State Management Hook

typescript
1export function useToggle(initialValue = false): [boolean, () => void] { 2 const [value, setValue] = useState(initialValue) 3 4 const toggle = useCallback(() => { 5 setValue(v => !v) 6 }, []) 7 8 return [value, toggle] 9} 10 11// Usage 12const [isOpen, toggleOpen] = useToggle()

Async Data Fetching Hook

typescript
1interface UseQueryOptions<T> { 2 onSuccess?: (data: T) => void 3 onError?: (error: Error) => void 4 enabled?: boolean 5} 6 7export function useQuery<T>( 8 key: string, 9 fetcher: () => Promise<T>, 10 options?: UseQueryOptions<T> 11) { 12 const [data, setData] = useState<T | null>(null) 13 const [error, setError] = useState<Error | null>(null) 14 const [loading, setLoading] = useState(false) 15 16 const refetch = useCallback(async () => { 17 setLoading(true) 18 setError(null) 19 20 try { 21 const result = await fetcher() 22 setData(result) 23 options?.onSuccess?.(result) 24 } catch (err) { 25 const error = err as Error 26 setError(error) 27 options?.onError?.(error) 28 } finally { 29 setLoading(false) 30 } 31 }, [fetcher, options]) 32 33 useEffect(() => { 34 if (options?.enabled !== false) { 35 refetch() 36 } 37 }, [key, refetch, options?.enabled]) 38 39 return { data, error, loading, refetch } 40} 41 42// Usage 43const { data: markets, loading, error, refetch } = useQuery( 44 'markets', 45 () => fetch('/api/markets').then(r => r.json()), 46 { 47 onSuccess: data => console.log('Fetched', data.length, 'markets'), 48 onError: err => console.error('Failed:', err) 49 } 50)

Debounce Hook

typescript
1export function useDebounce<T>(value: T, delay: number): T { 2 const [debouncedValue, setDebouncedValue] = useState<T>(value) 3 4 useEffect(() => { 5 const handler = setTimeout(() => { 6 setDebouncedValue(value) 7 }, delay) 8 9 return () => clearTimeout(handler) 10 }, [value, delay]) 11 12 return debouncedValue 13} 14 15// Usage 16const [searchQuery, setSearchQuery] = useState('') 17const debouncedQuery = useDebounce(searchQuery, 500) 18 19useEffect(() => { 20 if (debouncedQuery) { 21 performSearch(debouncedQuery) 22 } 23}, [debouncedQuery])

State Management Patterns

Context + Reducer Pattern

typescript
1interface State { 2 markets: Market[] 3 selectedMarket: Market | null 4 loading: boolean 5} 6 7type Action = 8 | { type: 'SET_MARKETS'; payload: Market[] } 9 | { type: 'SELECT_MARKET'; payload: Market } 10 | { type: 'SET_LOADING'; payload: boolean } 11 12function reducer(state: State, action: Action): State { 13 switch (action.type) { 14 case 'SET_MARKETS': 15 return { ...state, markets: action.payload } 16 case 'SELECT_MARKET': 17 return { ...state, selectedMarket: action.payload } 18 case 'SET_LOADING': 19 return { ...state, loading: action.payload } 20 default: 21 return state 22 } 23} 24 25const MarketContext = createContext<{ 26 state: State 27 dispatch: Dispatch<Action> 28} | undefined>(undefined) 29 30export function MarketProvider({ children }: { children: React.ReactNode }) { 31 const [state, dispatch] = useReducer(reducer, { 32 markets: [], 33 selectedMarket: null, 34 loading: false 35 }) 36 37 return ( 38 <MarketContext.Provider value={{ state, dispatch }}> 39 {children} 40 </MarketContext.Provider> 41 ) 42} 43 44export function useMarkets() { 45 const context = useContext(MarketContext) 46 if (!context) throw new Error('useMarkets must be used within MarketProvider') 47 return context 48}

Performance Optimization

Memoization

typescript
1// PASS: useMemo for expensive computations 2const sortedMarkets = useMemo(() => { 3 return markets.sort((a, b) => b.volume - a.volume) 4}, [markets]) 5 6// PASS: useCallback for functions passed to children 7const handleSearch = useCallback((query: string) => { 8 setSearchQuery(query) 9}, []) 10 11// PASS: React.memo for pure components 12export const MarketCard = React.memo<MarketCardProps>(({ market }) => { 13 return ( 14 <div className="market-card"> 15 <h3>{market.name}</h3> 16 <p>{market.description}</p> 17 </div> 18 ) 19})

Code Splitting & Lazy Loading

typescript
1import { lazy, Suspense } from 'react' 2 3// PASS: Lazy load heavy components 4const HeavyChart = lazy(() => import('./HeavyChart')) 5const ThreeJsBackground = lazy(() => import('./ThreeJsBackground')) 6 7export function Dashboard() { 8 return ( 9 <div> 10 <Suspense fallback={<ChartSkeleton />}> 11 <HeavyChart data={data} /> 12 </Suspense> 13 14 <Suspense fallback={null}> 15 <ThreeJsBackground /> 16 </Suspense> 17 </div> 18 ) 19}

Virtualization for Long Lists

typescript
1import { useVirtualizer } from '@tanstack/react-virtual' 2 3export function VirtualMarketList({ markets }: { markets: Market[] }) { 4 const parentRef = useRef<HTMLDivElement>(null) 5 6 const virtualizer = useVirtualizer({ 7 count: markets.length, 8 getScrollElement: () => parentRef.current, 9 estimateSize: () => 100, // Estimated row height 10 overscan: 5 // Extra items to render 11 }) 12 13 return ( 14 <div ref={parentRef} style={{ height: '600px', overflow: 'auto' }}> 15 <div 16 style={{ 17 height: `${virtualizer.getTotalSize()}px`, 18 position: 'relative' 19 }} 20 > 21 {virtualizer.getVirtualItems().map(virtualRow => ( 22 <div 23 key={virtualRow.index} 24 style={{ 25 position: 'absolute', 26 top: 0, 27 left: 0, 28 width: '100%', 29 height: `${virtualRow.size}px`, 30 transform: `translateY(${virtualRow.start}px)` 31 }} 32 > 33 <MarketCard market={markets[virtualRow.index]} /> 34 </div> 35 ))} 36 </div> 37 </div> 38 ) 39}

Form Handling Patterns

Controlled Form with Validation

typescript
1interface FormData { 2 name: string 3 description: string 4 endDate: string 5} 6 7interface FormErrors { 8 name?: string 9 description?: string 10 endDate?: string 11} 12 13export function CreateMarketForm() { 14 const [formData, setFormData] = useState<FormData>({ 15 name: '', 16 description: '', 17 endDate: '' 18 }) 19 20 const [errors, setErrors] = useState<FormErrors>({}) 21 22 const validate = (): boolean => { 23 const newErrors: FormErrors = {} 24 25 if (!formData.name.trim()) { 26 newErrors.name = 'Name is required' 27 } else if (formData.name.length > 200) { 28 newErrors.name = 'Name must be under 200 characters' 29 } 30 31 if (!formData.description.trim()) { 32 newErrors.description = 'Description is required' 33 } 34 35 if (!formData.endDate) { 36 newErrors.endDate = 'End date is required' 37 } 38 39 setErrors(newErrors) 40 return Object.keys(newErrors).length === 0 41 } 42 43 const handleSubmit = async (e: React.FormEvent) => { 44 e.preventDefault() 45 46 if (!validate()) return 47 48 try { 49 await createMarket(formData) 50 // Success handling 51 } catch (error) { 52 // Error handling 53 } 54 } 55 56 return ( 57 <form onSubmit={handleSubmit}> 58 <input 59 value={formData.name} 60 onChange={e => setFormData(prev => ({ ...prev, name: e.target.value }))} 61 placeholder="Market name" 62 /> 63 {errors.name && <span className="error">{errors.name}</span>} 64 65 {/* Other fields */} 66 67 <button type="submit">Create Market</button> 68 </form> 69 ) 70}

Error Boundary Pattern

typescript
1interface ErrorBoundaryState { 2 hasError: boolean 3 error: Error | null 4} 5 6export class ErrorBoundary extends React.Component< 7 { children: React.ReactNode }, 8 ErrorBoundaryState 9> { 10 state: ErrorBoundaryState = { 11 hasError: false, 12 error: null 13 } 14 15 static getDerivedStateFromError(error: Error): ErrorBoundaryState { 16 return { hasError: true, error } 17 } 18 19 componentDidCatch(error: Error, errorInfo: React.ErrorInfo) { 20 console.error('Error boundary caught:', error, errorInfo) 21 } 22 23 render() { 24 if (this.state.hasError) { 25 return ( 26 <div className="error-fallback"> 27 <h2>Something went wrong</h2> 28 <p>{this.state.error?.message}</p> 29 <button onClick={() => this.setState({ hasError: false })}> 30 Try again 31 </button> 32 </div> 33 ) 34 } 35 36 return this.props.children 37 } 38} 39 40// Usage 41<ErrorBoundary> 42 <App /> 43</ErrorBoundary>

Animation Patterns

Framer Motion Animations

typescript
1import { motion, AnimatePresence } from 'framer-motion' 2 3// PASS: List animations 4export function AnimatedMarketList({ markets }: { markets: Market[] }) { 5 return ( 6 <AnimatePresence> 7 {markets.map(market => ( 8 <motion.div 9 key={market.id} 10 initial={{ opacity: 0, y: 20 }} 11 animate={{ opacity: 1, y: 0 }} 12 exit={{ opacity: 0, y: -20 }} 13 transition={{ duration: 0.3 }} 14 > 15 <MarketCard market={market} /> 16 </motion.div> 17 ))} 18 </AnimatePresence> 19 ) 20} 21 22// PASS: Modal animations 23export function Modal({ isOpen, onClose, children }: ModalProps) { 24 return ( 25 <AnimatePresence> 26 {isOpen && ( 27 <> 28 <motion.div 29 className="modal-overlay" 30 initial={{ opacity: 0 }} 31 animate={{ opacity: 1 }} 32 exit={{ opacity: 0 }} 33 onClick={onClose} 34 /> 35 <motion.div 36 className="modal-content" 37 initial={{ opacity: 0, scale: 0.9, y: 20 }} 38 animate={{ opacity: 1, scale: 1, y: 0 }} 39 exit={{ opacity: 0, scale: 0.9, y: 20 }} 40 > 41 {children} 42 </motion.div> 43 </> 44 )} 45 </AnimatePresence> 46 ) 47}

Accessibility Patterns

Keyboard Navigation

typescript
1export function Dropdown({ options, onSelect }: DropdownProps) { 2 const [isOpen, setIsOpen] = useState(false) 3 const [activeIndex, setActiveIndex] = useState(0) 4 5 const handleKeyDown = (e: React.KeyboardEvent) => { 6 switch (e.key) { 7 case 'ArrowDown': 8 e.preventDefault() 9 setActiveIndex(i => Math.min(i + 1, options.length - 1)) 10 break 11 case 'ArrowUp': 12 e.preventDefault() 13 setActiveIndex(i => Math.max(i - 1, 0)) 14 break 15 case 'Enter': 16 e.preventDefault() 17 onSelect(options[activeIndex]) 18 setIsOpen(false) 19 break 20 case 'Escape': 21 setIsOpen(false) 22 break 23 } 24 } 25 26 return ( 27 <div 28 role="combobox" 29 aria-expanded={isOpen} 30 aria-haspopup="listbox" 31 onKeyDown={handleKeyDown} 32 > 33 {/* Dropdown implementation */} 34 </div> 35 ) 36}

Focus Management

typescript
1export function Modal({ isOpen, onClose, children }: ModalProps) { 2 const modalRef = useRef<HTMLDivElement>(null) 3 const previousFocusRef = useRef<HTMLElement | null>(null) 4 5 useEffect(() => { 6 if (isOpen) { 7 // Save currently focused element 8 previousFocusRef.current = document.activeElement as HTMLElement 9 10 // Focus modal 11 modalRef.current?.focus() 12 } else { 13 // Restore focus when closing 14 previousFocusRef.current?.focus() 15 } 16 }, [isOpen]) 17 18 return isOpen ? ( 19 <div 20 ref={modalRef} 21 role="dialog" 22 aria-modal="true" 23 tabIndex={-1} 24 onKeyDown={e => e.key === 'Escape' && onClose()} 25 > 26 {children} 27 </div> 28 ) : null 29}

Remember: Modern frontend patterns enable maintainable, performant user interfaces. Choose patterns that fit your project complexity.

FAQ & Installation Steps

These questions and steps mirror the structured data on this page for better search understanding.

? Frequently Asked Questions

What is frontend-patterns?

Perfect for Frontend Agents needing advanced React component composition and state management capabilities. Frontend development patterns for React, Next.js, state management, performance optimization, and UI best practices.

How do I install frontend-patterns?

Run the command: npx killer-skills add affaan-m/everything-claude-code/frontend-patterns. It works with Cursor, Windsurf, VS Code, Claude Code, and 19+ other IDEs.

What are the use cases for frontend-patterns?

Key use cases include: Implementing accessible and responsive UI patterns for React applications, Optimizing performance using memoization, virtualization, and code splitting techniques, Managing state with useState, useReducer, and Zustand for complex frontend logic.

Which IDEs are compatible with frontend-patterns?

This skill is compatible with Cursor, Windsurf, VS Code, Trae, Claude Code, OpenClaw, Aider, Codex, OpenCode, Goose, Cline, Roo Code, Kiro, Augment Code, Continue, GitHub Copilot, Sourcegraph Cody, and Amazon Q Developer. Use the Killer-Skills CLI for universal one-command installation.

Are there any limitations for frontend-patterns?

Requires React or Next.js project setup. Familiarity with JavaScript and TypeScript necessary. Limited to frontend development, not applicable to backend or full-stack development.

How To Install

  1. 1. Open your terminal

    Open the terminal or command line in your project directory.

  2. 2. Run the install command

    Run: npx killer-skills add affaan-m/everything-claude-code/frontend-patterns. The CLI will automatically detect your IDE or AI agent and configure the skill.

  3. 3. Start using the skill

    The skill is now active. Your AI agent can use frontend-patterns immediately in the current project.

Related Skills

Looking for an alternative to frontend-patterns or another official skill for your workflow? Explore these related open-source skills.

View All

flags

Logo of facebook
facebook

Use when you need to check feature flag states, compare channels, or debug why a feature behaves differently across release channels.

243.6k
0
Developer

extract-errors

Logo of facebook
facebook

Use when adding new error messages to React, or seeing unknown error code warnings.

243.6k
0
Developer

fix

Logo of facebook
facebook

Use when you have lint errors, formatting issues, or before committing code to ensure it passes CI.

243.6k
0
Developer

flow

Logo of facebook
facebook

Use when you need to run Flow type checking, or when seeing Flow type errors in React code.

243.6k
0
Developer