Awesome-omni-skill senior-frontend
Expert frontend development with React, Vue, and modern frameworks including component architecture, state management, performance optimization, and accessibility.
install
source · Clone the upstream repo
git clone https://github.com/diegosouzapw/awesome-omni-skill
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/diegosouzapw/awesome-omni-skill "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/development/senior-frontend" ~/.claude/skills/diegosouzapw-awesome-omni-skill-senior-frontend-a231dc && rm -rf "$T"
manifest:
skills/development/senior-frontend/SKILL.mdsource content
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:
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:
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:
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:
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:
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
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
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:
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
/* 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:
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:
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
// 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
// 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
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
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
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
- Advanced React patternsreferences/react_patterns.md
- CSS organizationreferences/css_architecture.md
- A11y guidelinesreferences/accessibility.md
- Performance optimizationreferences/performance.md
Scripts
# 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