Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Use this skill when building multi-component web applications, interactive dashboards, complex React apps with state management, or any web artifact that requires routing, multiple views, or sophisticated UI interactions. Trigger on keywords: build a web app, dashboard, multi-page, React app, interactive tool, web application, complex UI, build a tool that.
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-09 | ✗→✓ | ▲ Improved | -2% | 0% |
| case-12 | ✗→✓ | ▲ Improved | 35% | 0% |
| case-18 | ✗→✓ | ▲ Improved | 3% | 0% |
| case-15 | ✓→✓ | = Same ✓ | -14% | 0% |
| case-04 | ✓→✓ | = Same ✓ | 138% | 0% |
Use for complex, multi-component applications. For simple single components, use frontend-design instead.
Signs you need this skill:
Framework: Next.js 15 (App Router) or React 19
Styling: Tailwind CSS v4
Components: shadcn/ui (accessible primitives)
State: Zustand (client) + TanStack Query (server)
Forms: React Hook Form + Zod
Animation: Motion (formerly Framer Motion)
Icons: Lucide Reactsrc/
├── app/ # Next.js App Router pages
│ ├── layout.tsx # Root layout
│ ├── page.tsx # Home page
│ └── [feature]/
│ └── page.tsx
├── components/
│ ├── ui/ # shadcn/ui components
│ └── [feature]/ # Feature-specific components
├── lib/
│ ├── utils.ts # Shared utilities
│ └── validations.ts # Zod schemas
├── hooks/ # Custom React hooks
├── stores/ # Zustand stores
└── types/ # TypeScript typestsximport { Button } from "@/components/ui/button" import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" import { Input } from "@/components/ui/input" import { Label } from "@/components/ui/label" import { Badge } from "@/components/ui/badge" import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog"
Always use shadcn/ui primitives for standard UI elements — they're accessible by default and consistent.
typescript// Zustand store import { create } from 'zustand' interface AppStore { user: User | null setUser: (user: User | null) => void selectedItems: string[] toggleItem: (id: string) => void clearSelection: () => void } export const useAppStore = create<AppStore>((set) => ({ user: null, setUser: (user) => set({ user }), selectedItems: [], toggleItem: (id) => set((state) => ({ selectedItems: state.selectedItems.includes(id) ? state.selectedItems.filter(i => i !== id) : [...state.selectedItems, id] })), clearSelection: () => set({ selectedItems: [] }) }))
typescript// TanStack Query for server state import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query' export function useUsers() { return useQuery({ queryKey: ['users'], queryFn: () => fetch('/api/users').then(r => r.json()), staleTime: 5 * 60 * 1000 // 5 minutes }) } export function useCreateUser() { const queryClient = useQueryClient() return useMutation({ mutationFn: (data: CreateUserInput) => fetch('/api/users', { method: 'POST', body: JSON.stringify(data) }), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['users'] }) } }) }
Before shipping any web artifact:
any)Other measured skills in the registry, with their headline benchmark lift.