React component patterns, state management, accessibility, and frontend best practices. Use when building UI components or implementing client-side features.
View on GitHubFebruary 1, 2026
Select agents to install to:
npx add-skill https://github.com/mnthe/hardworker-marketplace/blob/main/plugins/ultrawork/skills/frontend-patterns/SKILL.md -a claude-code --skill frontend-patternsInstallation paths:
.claude/skills/frontend-patterns/# Frontend Patterns
Comprehensive patterns for React components, state management, accessibility, and modern frontend development.
## When to Use
- Building React components
- Managing client state
- Implementing user interactions
- Handling forms and validation
- Optimizing performance
- Ensuring accessibility
## Component Patterns
### Component Structure
```typescript
// ✅ CORRECT: Well-structured component
'use client'
import { useState, useEffect } from 'react'
import { Button } from '@/components/ui/Button'
import { LoadingSpinner } from '@/components/ui/LoadingSpinner'
interface MarketCardProps {
id: string
name: string
description: string
endDate: Date
onBet?: (marketId: string, outcome: string) => void
}
export function MarketCard({
id,
name,
description,
endDate,
onBet
}: MarketCardProps) {
const [isLoading, setIsLoading] = useState(false)
const handleBet = async (outcome: string) => {
setIsLoading(true)
try {
await onBet?.(id, outcome)
} finally {
setIsLoading(false)
}
}
return (
<div className="border rounded-lg p-4" data-testid="market-card">
<h3 className="text-xl font-bold">{name}</h3>
<p className="text-gray-600">{description}</p>
<div className="mt-4 flex gap-2">
<Button
onClick={() => handleBet('yes')}
disabled={isLoading}
aria-label={`Bet yes on ${name}`}
>
{isLoading ? <LoadingSpinner /> : 'Yes'}
</Button>
<Button
onClick={() => handleBet('no')}
disabled={isLoading}
aria-label={`Bet no on ${name}`}
>
{isLoading ? <LoadingSpinner /> : 'No'}
</Button>
</div>
</div>
)
}
```
### Compound Component Pattern
```typescript
// Flexible, composable components
interface TabsContextValue {
activeTab: string
setActiveTab: (tab: string) => void
}
const TabsContext = createContext<TabsContextValue | null>(null)
export function Ta