| name | senior-frontend |
| description | Frontend development skill for React, Next.js, TypeScript, and Tailwind CSS applications. Use when building React components, optimizing Next.js performance, analyzing bundle sizes, scaffolding frontend projects, implementing accessibility, or reviewing frontend code quality. |
Senior Frontend
Frontend development patterns, performance optimization, and automation tools for React/Next.js applications.
Project Scaffolding
Generate a new Next.js or React project with TypeScript, Tailwind CSS, and best practice configurations.
Scaffolder Options
| Option | Description |
|---|
--template nextjs | Next.js 14+ with App Router and Server Components |
--template react | React + Vite with TypeScript |
--features auth | Add NextAuth.js authentication |
--features api | Add React Query + API client |
--features forms | Add React Hook Form + Zod validation |
--features testing | Add Vitest + Testing Library |
Generated Structure (Next.js)
my-app/
āāā app/
ā āāā layout.tsx # Root layout with fonts
ā āāā page.tsx # Home page
ā āāā globals.css # Tailwind + CSS variables
ā āāā api/health/route.ts
āāā components/
ā āāā ui/ # Button, Input, Card
ā āāā layout/ # Header, Footer, Sidebar
āāā hooks/ # useDebounce, useLocalStorage
āāā lib/ # utils (cn), constants
āāā types/ # TypeScript interfaces
āāā tailwind.config.ts
āāā next.config.js
āāā package.json
Component Generation
Generate React components with TypeScript, tests, and Storybook stories.
Generator Options
| Option | Description |
|---|
--type client | Client component with 'use client' (default) |
--type server | Async server component |
--type hook | Custom React hook |
--with-test | Include test file |
--with-story | Include Storybook story |
Bundle Analysis
Analyze package.json and project structure for bundle optimization opportunities.
Heavy Dependencies to Replace
| Package | Size | Alternative |
|---|
| moment | 290KB | date-fns (12KB) or dayjs (2KB) |
| lodash | 71KB | lodash-es with tree-shaking |
| axios | 14KB | Native fetch or ky (3KB) |
| jquery | 87KB | Native DOM APIs |
| @mui/material | Large | shadcn/ui or Radix UI |
React Patterns
Compound Components
const Tabs = ({ children }) => {
const [active, setActive] = useState(0);
return (
<TabsContext.Provider value={{ active, setActive }}>
{children}
</TabsContext.Provider>
);
};
Tabs.List = TabList;
Tabs.Panel = TabPanel;
Custom Hooks
function useDebounce<T>(value: T, delay = 500): T {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const timer = setTimeout(() => setDebouncedValue(value), delay);
return () => clearTimeout(timer);
}, [value, delay]);
return debouncedValue;
}
Next.js Optimization
Server vs Client Components
Use Server Components by default. Add 'use client' only when you need:
- Event handlers (onClick, onChange)
- State (useState, useReducer)
- Effects (useEffect)
- Browser APIs
Image Optimization
import Image from 'next/image';
<Image
src="/hero.jpg"
alt="Hero"
width={1200}
height={600}
priority
/>
<div className="relative aspect-video">
<Image
src="/product.jpg"
alt="Product"
fill
sizes="(max-width: 768px) 100vw, 50vw"
className="object-cover"
/>
</div>
Accessibility Checklist
- Semantic HTML: Use proper elements (
<button>, <nav>, <main>)
- Keyboard Navigation: All interactive elements focusable
- ARIA Labels: Provide labels for icons and complex widgets
- Color Contrast: Minimum 4.5:1 for normal text
- Focus Indicators: Visible focus states
<button
type="button"
aria-label="Close dialog"
onClick={onClose}
className="focus-visible:ring-2 focus-visible:ring-blue-500"
>
<XIcon aria-hidden="true" />
</button>
Quick Reference
Tailwind CSS Utilities
import { cn } from '@/lib/utils';
<button className={cn(
'px-4 py-2 rounded',
variant === 'primary' && 'bg-blue-500 text-white',
disabled && 'opacity-50 cursor-not-allowed'
)} />
TypeScript Patterns
interface CardProps {
className?: string;
children: React.ReactNode;
}
interface ListProps<T> {
items: T[];
renderItem: (item: T) => React.ReactNode;
}
function List<T>({ items, renderItem }: ListProps<T>) {
return <ul>{items.map(renderItem)}</ul>;
}