
Frontend Patterns
Give your coding agent consistent React and Next.js composition, state, and performance patterns while you ship UI.
Overview
Frontend Patterns is a journey-wide agent skill that teaches React and Next.js component composition, state, and performance habits—usable whenever a solo builder implements or refactors UI before shipping.
Install
npx skills add https://github.com/davila7/claude-code-templates --skill frontend-patternsWhat is this skill?
- Composition-over-inheritance and compound-component patterns with TypeScript examples
- React and Next.js-oriented structure for cards, tabs, and reusable UI primitives
- State management and performance optimization guidance for modern SPAs
- Concrete good vs. anti-pattern snippets agents can paste and adapt
- UI best-practice framing for performant user interfaces
Adoption & trust: 582 installs on skills.sh; 27.8k GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
Your agent keeps generating inconsistent React structures, prop drilling, and ad-hoc UI patterns that are hard to maintain across features.
Who is it for?
Solo builders actively coding React or Next.js who want the agent to mirror proven component APIs instead of one-off markup.
Skip if: Teams on Vue, Svelte, or plain HTML-only stacks, or when you already enforce a locked component library the skill would contradict.
When should I use this skill?
Frontend development with React, Next.js, or when you need state management, performance optimization, and UI best-practice examples.
What do I get? / Deliverables
The agent applies documented composition, compound-component, and performance patterns so new screens match your established frontend style.
- Refactored or new components following documented patterns
- Consistent compound-component APIs across features
Recommended Skills
Journey fit
Useful at every journey phase - explore requirements and options before committing to a direction.
Where it fits
Shape a clickable Next.js prototype using compound Tab and Card patterns before committing to the full build.
Implement new settings and billing screens with shared composition APIs instead of one-off div stacks.
Refactor list and dashboard views using the skill’s performance guidance before launch.
Extend marketing or in-app content modules with the same CardHeader/CardBody structure for faster iteration.
How it compares
Use as procedural frontend reference patterns, not as an MCP server or automated design-to-code pipeline.
Common Questions / FAQ
Who is frontend-patterns for?
Indie and solo developers using Claude Code, Cursor, or Codex to build React or Next.js interfaces who want repeatable component and performance conventions in agent sessions.
When should I use frontend-patterns?
During Build when scaffolding features, during Ship when refactoring for performance, during Validate when tightening a prototype UI, and during Grow when extending dashboards—whenever you want consistent React/Next patterns.
Is frontend-patterns safe to install?
It is pattern documentation without declared shell or network calls in the excerpt; review the Security Audits panel on this Prism page before installing from any third-party skills repo.
SKILL.md
READMESKILL.md - Frontend Patterns
# Frontend Development Patterns Modern frontend patterns for React, Next.js, and performant user interfaces. ## Component Patterns ### Composition Over Inheritance ```typescript // ✅ GOOD: Component composition interface CardProps { children: React.ReactNode variant?: 'default' | 'outlined' } export function Card({ children, variant = 'default' }: CardProps) { return <div className={`card card-${variant}`}>{children}</div> } export function CardHeader({ children }: { children: React.ReactNode }) { return <div className="card-header">{children}</div> } export function CardBody({ children }: { children: React.ReactNode }) { return <div className="card-body">{children}</div> } // Usage <Card> <CardHeader>Title</CardHeader> <CardBody>Content</CardBody> </Card> ``` ### Compound Components ```typescript interface TabsContextValue { activeTab: string setActiveTab: (tab: string) => void } const TabsContext = createContext<TabsContextValue | undefined>(undefined) export function Tabs({ children, defaultTab }: { children: React.ReactNode defaultTab: string }) { const [activeTab, setActiveTab] = useState(defaultTab) return ( <TabsContext.Provider value={{ activeTab, setActiveTab }}> {children} </TabsContext.Provider> ) } export function TabList({ children }: { children: React.ReactNode }) { return <div className="tab-list">{children}</div> } export function Tab({ id, children }: { id: string, children: React.ReactNode }) { const context = useContext(TabsContext) if (!context) throw new Error('Tab must be used within Tabs') return ( <button className={context.activeTab === id ? 'active' : ''} onClick={() => context.setActiveTab(id)} > {children} </button> ) } // Usage <Tabs defaultTab="overview"> <TabList> <Tab id="overview">Overview</Tab> <Tab id="details">Details</Tab> </TabList> </Tabs> ``` ### Render Props Pattern ```typescript interface DataLoaderProps<T> { url: string children: (data: T | null, loading: boolean, error: Error | null) => React.ReactNode } export function DataLoader<T>({ url, children }: DataLoaderProps<T>) { const [data, setData] = useState<T | null>(null) const [loading, setLoading] = useState(true) const [error, setError] = useState<Error | null>(null) useEffect(() => { fetch(url) .then(res => res.json()) .then(setData) .catch(setError) .finally(() => setLoading(false)) }, [url]) return <>{children(data, loading, error)}</> } // Usage <DataLoader<Market[]> url="/api/markets"> {(markets, loading, error) => { if (loading) return <Spinner /> if (error) return <Error error={error} /> return <MarketList markets={markets!} /> }} </DataLoader> ``` ## Custom Hooks Patterns ### State Management Hook ```typescript export function useToggle(initialValue = false): [boolean, () => void] { const [value, setValue] = useState(initialValue) const toggle = useCallback(() => { setValue(v => !v) }, []) return [value, toggle] } // Usage const [isOpen, toggleOpen] = useToggle() ``` ### Async Data Fetching Hook ```typescript interface UseQueryOptions<T> { onSuccess?: (data: T) => void onError?: (error: Error) => void enabled?: boolean } export function useQuery<T>( key: string, fetcher: () => Promise<T>, options?: UseQueryOptions<T> ) { const [data, setData] = useState<T | null>(null) const [error, setError] = useState<Error | null>(null) const [loading, setLoading] = useState(false) const refetch = useCallback(async () => { setLoading(true) setError(null) try { const result = await fetcher() setData(result) options?.onSuccess?.(result) } catch (err) { const error = err as Error setErro