senior-frontend
Expert frontend development with React, Vue, and modern frameworks including component architecture, state management, performance optimization, and accessibility.
Best use case
senior-frontend is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Expert frontend development with React, Vue, and modern frameworks including component architecture, state management, performance optimization, and accessibility.
Teams using senior-frontend should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/senior-frontend/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How senior-frontend Compares
| Feature / Agent | senior-frontend | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Expert frontend development with React, Vue, and modern frameworks including component architecture, state management, performance optimization, and accessibility.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Senior Frontend Developer
Expert-level frontend development for modern web applications.
## Core Competencies
- Component architecture
- State management
- Performance optimization
- Accessibility (a11y)
- CSS architecture
- Build optimization
- Testing strategies
- Design system implementation
## Framework Comparison
| Feature | React | Vue | Svelte |
|---------|-------|-----|--------|
| Learning Curve | Medium | Low | Low |
| Bundle Size | Medium | Small | Smallest |
| Ecosystem | Largest | Large | Growing |
| Performance | Excellent | Excellent | Best |
| Enterprise Use | Highest | High | Medium |
## React Patterns
### Component Patterns
**Presentational Component:**
```typescript
interface ButtonProps {
variant: 'primary' | 'secondary';
size: 'sm' | 'md' | 'lg';
disabled?: boolean;
children: React.ReactNode;
onClick?: () => void;
}
export function Button({
variant,
size,
disabled,
children,
onClick
}: ButtonProps) {
return (
<button
className={cn(
'button',
`button--${variant}`,
`button--${size}`,
disabled && 'button--disabled'
)}
disabled={disabled}
onClick={onClick}
>
{children}
</button>
);
}
```
**Container Component:**
```typescript
export function UserListContainer() {
const { data: users, isLoading, error } = useUsers();
if (isLoading) return <Skeleton count={5} />;
if (error) return <ErrorMessage error={error} />;
return <UserList users={users} />;
}
```
**Higher-Order Component:**
```typescript
function withAuth<P extends object>(Component: React.ComponentType<P>) {
return function AuthenticatedComponent(props: P) {
const { user, isLoading } = useAuth();
if (isLoading) return <Loading />;
if (!user) return <Navigate to="/login" />;
return <Component {...props} />;
};
}
```
### Custom Hooks
**Data Fetching Hook:**
```typescript
function useApi<T>(url: string, options?: RequestInit) {
const [data, setData] = useState<T | null>(null);
const [error, setError] = useState<Error | null>(null);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
const controller = new AbortController();
async function fetchData() {
try {
setIsLoading(true);
const response = await fetch(url, {
...options,
signal: controller.signal,
});
if (!response.ok) throw new Error('Request failed');
const json = await response.json();
setData(json);
} catch (err) {
if (err.name !== 'AbortError') {
setError(err as Error);
}
} finally {
setIsLoading(false);
}
}
fetchData();
return () => controller.abort();
}, [url]);
return { data, error, isLoading };
}
```
**Local Storage Hook:**
```typescript
function useLocalStorage<T>(key: string, initialValue: T) {
const [storedValue, setStoredValue] = useState<T>(() => {
if (typeof window === 'undefined') return initialValue;
try {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch {
return initialValue;
}
});
const setValue = (value: T | ((val: T) => T)) => {
const valueToStore = value instanceof Function ? value(storedValue) : value;
setStoredValue(valueToStore);
window.localStorage.setItem(key, JSON.stringify(valueToStore));
};
return [storedValue, setValue] as const;
}
```
## State Management
### Zustand
```typescript
import { create } from 'zustand';
import { persist } from 'zustand/middleware';
interface CartStore {
items: CartItem[];
addItem: (item: CartItem) => void;
removeItem: (id: string) => void;
clearCart: () => void;
total: () => number;
}
export const useCartStore = create<CartStore>()(
persist(
(set, get) => ({
items: [],
addItem: (item) =>
set((state) => ({
items: [...state.items, item],
})),
removeItem: (id) =>
set((state) => ({
items: state.items.filter((item) => item.id !== id),
})),
clearCart: () => set({ items: [] }),
total: () =>
get().items.reduce((sum, item) => sum + item.price * item.quantity, 0),
}),
{ name: 'cart-storage' }
)
);
```
### React Query
```typescript
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
// Query
function useProducts(category: string) {
return useQuery({
queryKey: ['products', category],
queryFn: () => fetchProducts(category),
staleTime: 5 * 60 * 1000,
});
}
// Mutation
function useCreateProduct() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: createProduct,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['products'] });
},
});
}
// Optimistic Update
function useUpdateProduct() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: updateProduct,
onMutate: async (newProduct) => {
await queryClient.cancelQueries({ queryKey: ['products', newProduct.id] });
const previous = queryClient.getQueryData(['products', newProduct.id]);
queryClient.setQueryData(['products', newProduct.id], newProduct);
return { previous };
},
onError: (err, newProduct, context) => {
queryClient.setQueryData(['products', newProduct.id], context?.previous);
},
onSettled: (data, error, variables) => {
queryClient.invalidateQueries({ queryKey: ['products', variables.id] });
},
});
}
```
## CSS Architecture
### Tailwind CSS Best Practices
**Component Classes:**
```typescript
const buttonVariants = cva(
'inline-flex items-center justify-center rounded-md font-medium transition-colors',
{
variants: {
variant: {
primary: 'bg-blue-600 text-white hover:bg-blue-700',
secondary: 'bg-gray-200 text-gray-900 hover:bg-gray-300',
outline: 'border border-gray-300 hover:bg-gray-100',
},
size: {
sm: 'h-8 px-3 text-sm',
md: 'h-10 px-4 text-base',
lg: 'h-12 px-6 text-lg',
},
},
defaultVariants: {
variant: 'primary',
size: 'md',
},
}
);
```
### CSS Modules
```css
/* Button.module.css */
.button {
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: 0.375rem;
font-weight: 500;
transition: all 0.2s;
}
.primary {
background-color: var(--color-primary);
color: white;
}
.primary:hover {
background-color: var(--color-primary-dark);
}
```
## Accessibility
### ARIA Patterns
**Modal Dialog:**
```typescript
function Modal({ isOpen, onClose, title, children }) {
const modalRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (isOpen) {
modalRef.current?.focus();
}
}, [isOpen]);
if (!isOpen) return null;
return (
<div
role="dialog"
aria-modal="true"
aria-labelledby="modal-title"
ref={modalRef}
tabIndex={-1}
onKeyDown={(e) => e.key === 'Escape' && onClose()}
>
<h2 id="modal-title">{title}</h2>
{children}
<button onClick={onClose} aria-label="Close modal">
Close
</button>
</div>
);
}
```
**Tab Panel:**
```typescript
function Tabs({ tabs, activeTab, onChange }) {
return (
<div>
<div role="tablist" aria-label="Content tabs">
{tabs.map((tab, index) => (
<button
key={tab.id}
role="tab"
aria-selected={activeTab === index}
aria-controls={`panel-${tab.id}`}
id={`tab-${tab.id}`}
tabIndex={activeTab === index ? 0 : -1}
onClick={() => onChange(index)}
>
{tab.label}
</button>
))}
</div>
{tabs.map((tab, index) => (
<div
key={tab.id}
role="tabpanel"
id={`panel-${tab.id}`}
aria-labelledby={`tab-${tab.id}`}
hidden={activeTab !== index}
>
{tab.content}
</div>
))}
</div>
);
}
```
### Accessibility Checklist
- [ ] Keyboard navigation works
- [ ] Focus indicators visible
- [ ] Color contrast meets WCAG AA
- [ ] Images have alt text
- [ ] Form inputs have labels
- [ ] Error messages are announced
- [ ] Skip links present
- [ ] Heading hierarchy correct
- [ ] ARIA labels for icons
- [ ] Motion respects user preferences
## Performance Optimization
### Code Splitting
```typescript
// Route-based splitting
const Dashboard = lazy(() => import('./pages/Dashboard'));
const Settings = lazy(() => import('./pages/Settings'));
// Component-based splitting
const HeavyChart = lazy(() => import('./components/HeavyChart'));
// Named exports
const { DataTable } = lazy(() =>
import('./components/DataTable').then((module) => ({
default: module.DataTable,
}))
);
```
### Memoization
```typescript
// Memoize expensive component
const ExpensiveList = memo(function ExpensiveList({ items, onSelect }) {
return (
<ul>
{items.map((item) => (
<li key={item.id} onClick={() => onSelect(item.id)}>
{item.name}
</li>
))}
</ul>
);
});
// Memoize callback
function Parent() {
const [selected, setSelected] = useState<string | null>(null);
const handleSelect = useCallback((id: string) => {
setSelected(id);
}, []);
return <ExpensiveList items={items} onSelect={handleSelect} />;
}
// Memoize computed value
function DataDisplay({ data }) {
const processedData = useMemo(() => {
return data.map(expensiveTransform).filter(expensiveFilter);
}, [data]);
return <Chart data={processedData} />;
}
```
### Virtual Lists
```typescript
import { useVirtualizer } from '@tanstack/react-virtual';
function VirtualList({ items }) {
const parentRef = useRef<HTMLDivElement>(null);
const virtualizer = useVirtualizer({
count: items.length,
getScrollElement: () => parentRef.current,
estimateSize: () => 50,
overscan: 5,
});
return (
<div ref={parentRef} style={{ height: '400px', overflow: 'auto' }}>
<div
style={{
height: `${virtualizer.getTotalSize()}px`,
position: 'relative',
}}
>
{virtualizer.getVirtualItems().map((virtualItem) => (
<div
key={virtualItem.key}
style={{
position: 'absolute',
top: 0,
transform: `translateY(${virtualItem.start}px)`,
height: `${virtualItem.size}px`,
}}
>
{items[virtualItem.index].name}
</div>
))}
</div>
</div>
);
}
```
## Testing
### Component Testing
```typescript
import { render, screen, fireEvent } from '@testing-library/react';
describe('Button', () => {
it('renders with correct text', () => {
render(<Button>Click me</Button>);
expect(screen.getByRole('button', { name: 'Click me' })).toBeInTheDocument();
});
it('calls onClick when clicked', () => {
const onClick = jest.fn();
render(<Button onClick={onClick}>Click me</Button>);
fireEvent.click(screen.getByRole('button'));
expect(onClick).toHaveBeenCalledTimes(1);
});
it('is disabled when disabled prop is true', () => {
render(<Button disabled>Click me</Button>);
expect(screen.getByRole('button')).toBeDisabled();
});
});
```
### Hook Testing
```typescript
import { renderHook, act } from '@testing-library/react';
describe('useCounter', () => {
it('increments counter', () => {
const { result } = renderHook(() => useCounter(0));
act(() => {
result.current.increment();
});
expect(result.current.count).toBe(1);
});
});
```
## Reference Materials
- `references/react_patterns.md` - Advanced React patterns
- `references/css_architecture.md` - CSS organization
- `references/accessibility.md` - A11y guidelines
- `references/performance.md` - Performance optimization
## Scripts
```bash
# Component scaffolder
python scripts/component_gen.py --name Button --type atom
# Bundle analyzer
python scripts/bundle_analyzer.py --build-dir ./dist
# Accessibility audit
python scripts/a11y_audit.py --url http://localhost:3000
# Performance report
python scripts/perf_report.py --lighthouse-json report.json
```Related Skills
software-frontend
Production-grade frontend development with Next.js 16 App Router, TypeScript 5.9+ strict mode, Tailwind CSS v4, shadcn/ui, React 19.2 Server Components, state management (Zustand/Recoil), performance optimization (Turbopack stable, ISR/SSR/SSG), and accessibility best practices. Includes TanStack Query for server-state, Vitest for testing, and modern React patterns.
senior-software-developer
Provides production-quality patterns, standards, and language-specific best practices for Python, C#, Node.js, and TypeScript. Used as the implementation guideline within test-driven-development workflow, or directly for architecture decisions and complex refactoring. Not invoked directly for new feature implementation - use test-driven-development instead.
senior-qa
Comprehensive QA and testing skill for quality assurance, test automation, and testing strategies for ReactJS, NextJS, NodeJS applications. Includes test suite generation, coverage analysis, E2E testing setup, and quality metrics. Use when designing test strategies, writing test cases, implementing test automation, performing manual testing, or analyzing test coverage.
senior-fullstack
Fullstack development toolkit with project scaffolding for Next.js/FastAPI/MERN/Django stacks and code quality analysis. Use when scaffolding new projects, analyzing codebase quality, or implementing fullstack architecture patterns.
senior-fullstack-ai-engineer
Senior full-stack developer with 10+ years of experience and AI engineering expertise. Builds production-ready applications using modern frameworks (Flask, FastAPI, React), AI/ML technologies (LLMs, RAG, model deployment), and cloud infrastructure. Use for all development tasks requiring full-stack and AI/ML implementation.
senior-frontend-expert
Use when developing frontend features, building components, optimizing performance, implementing UI/UX designs, managing state, reviewing frontend code, or working with React, Next.js, TypeScript, TailwindCSS, or CSS. Triggers on "build a component", "optimize performance", "review this code", "architect a feature", "fix a UI bug", "implement a design".
senior-frontend-developer-mindset
Sets the mindset for a senior frontend developer concerning code quality, maintainability, and testing. This encourages developers to focus on creating clean, efficient, and well-tested code.
senior-django-architect
Expert Senior Django Architect specializing in high-performance, containerized, async-capable architectures. Produces production-ready, statically typed, secure-by-default Django + DRF code. Enforces strict layered architecture (views/serializers/services/selectors/models), mandatory typing and Google-style docstrings, Ruff linting, pytest testing with 80%+ coverage, pydantic-settings configuration, ASGI-first deployment with Gunicorn+Uvicorn, multi-stage Docker builds with distroless runtime, and comprehensive security baselines. All code must be complete with zero placeholders.
senior-devops
Senior DevOps engineering skill covering CI/CD pipeline design, infrastructure as code with Terraform, container orchestration with Kubernetes, cloud platform architecture (AWS, GCP, Azure), deployment strategies, monitoring and observability, and security hardening. Provides pipeline generation, Terraform scaffolding, and deployment management automation. Use when the user needs to build CI/CD pipelines, containerize applications, manage Kubernetes clusters, provision cloud infrastructure, implement deployment strategies, set up monitoring, optimize cloud costs, or handle incident response.
senior-backend
Expert backend development covering API design, database architecture, microservices, message queues, caching, and system scalability.
senior-architect
This skill should be used when the user asks to "design system architecture", "evaluate microservices vs monolith", "create architecture diagrams", "analyze dependencies", "choose a database", "plan for scalability", "make technical decisions", or "review system design". Use for architecture decision records (ADRs), tech stack evaluation, system design reviews, dependency analysis, and generating architecture diagrams in Mermaid, PlantUML, or ASCII format.
sarvam-style-frontend
Build high-confidence, India-first AI product sites with a clean, assertive, enterprise aesthetic using React + Framer Motion.