git clone https://github.com/vibeforge1111/vibeship-spawner-skills
frontend/v0-dev/skill.yamlv0.dev Skill
Vercel's AI-powered UI component generation
id: v0-dev name: v0.dev version: 1.0.0 layer: 2 # Integration layer
description: | Expert in using v0.dev for AI-powered UI generation. Covers prompting strategies, component iteration, shadcn/ui integration, export workflows, and customization. Knows how to get the best results from v0 and integrate generated components into production codebases.
owns:
- v0 prompting strategies
- Component iteration
- shadcn/ui patterns
- Export and integration
- Design system alignment
- Accessibility in generated code
pairs_with:
- nextjs-app-router
- react-patterns
- tailwind
requires:
- v0.dev account
- Next.js or React project
- shadcn/ui setup (recommended)
ecosystem: primary: - v0.dev - shadcn/ui - Radix UI common_integrations: - Next.js - React - Tailwind CSS - Vercel output_formats: - React components - TypeScript - Tailwind classes
prerequisites:
- React fundamentals
- Tailwind CSS basics
- Component architecture
limits:
- Can't access your codebase directly
- Limited to shadcn/ui components
- May need customization
- Generated code style varies
tags:
- v0
- v0-dev
- ui-generation
- shadcn
- component-generation
- ai-ui
- vercel
triggers:
- "v0"
- "v0.dev"
- "generate ui"
- "shadcn component"
- "ai component"
- "generate component"
history:
- version: "1.0.0" date: "2025-01" changes: "Initial skill covering v0.dev patterns"
contrarian_insights:
- claim: "Just describe what you want" counter: "Specific, structured prompts with constraints produce better results" evidence: "Adding 'use shadcn Button' beats 'add a button' every time"
- claim: "v0 output is production-ready" counter: "Generated code needs review for accessibility, edge cases, and style" evidence: "Common issues: missing aria labels, hardcoded values, inconsistent naming"
- claim: "Generate entire pages at once" counter: "Build component-by-component for better control and reusability" evidence: "Small focused prompts iterate faster and produce cleaner components"
identity: role: v0.dev UI Architect personality: | You are an expert in AI-assisted UI development with v0.dev. You understand that prompting is a skill - specific, constrained prompts produce better results than vague descriptions. You think in terms of components, design systems, and accessibility. You know when to use v0 and when to code by hand. expertise: - Prompt engineering for UI - shadcn/ui component library - Design system integration - Component architecture
patterns:
-
name: Effective Prompting description: Structure prompts for best results when_to_use: Any v0 generation implementation: |
Prompt Structure for Best Results:
1. Be Specific About Components
BAD
"Create a login form"
GOOD
"Create a login form with:
- Email input with validation
- Password input with show/hide toggle
- 'Remember me' checkbox
- Submit button (disabled until valid)
- 'Forgot password' link
- Social login buttons (Google, GitHub) Use shadcn/ui Card, Input, Button, Checkbox components"
2. Specify Design Constraints
BAD
"Make it look nice"
GOOD
"Design constraints:
- Max width 400px, centered
- Dark mode support
- Mobile-first responsive
- Subtle shadows, rounded corners
- Primary color for submit button"
3. Include Behavior
BAD
"Add form handling"
GOOD
"Behavior:
- Show loading spinner on submit
- Display error message below form on failure
- Disable form while submitting
- Redirect on success (placeholder)"
4. Reference Existing Patterns
BAD
"Like a modern app"
GOOD
"Similar to:
- Vercel dashboard login
- Linear app onboarding
- Stripe checkout form style"
5. Mention Accessibility
"Ensure:
- Proper label associations
- Focus states visible
- Error messages announced to screen readers
- Keyboard navigation works"
-
name: Component Iteration description: Refine components through conversation when_to_use: Improving generated output implementation: |
Iteration Strategy:
Step 1: Generate Base Component
"Create a pricing card with:
- Plan name and price
- Feature list with check icons
- CTA button Use shadcn Card and Button"
Step 2: Refine Specific Elements
"Update the pricing card:
- Make the 'Pro' plan highlighted with a border
- Add 'Most Popular' badge
- Show annual/monthly toggle price"
Step 3: Add States
"Add to the pricing card:
- Hover state with subtle scale
- Loading state for CTA button
- Disabled state for unavailable plans"
Step 4: Improve Responsive
"Make pricing cards:
- Stack vertically on mobile
- 3 columns on desktop
- Equal heights in row"
Step 5: Polish Details
"Final touches:
- Add subtle gradient to highlighted card
- Animate feature list on hover
- Add tooltip for 'i' icons"
Tips for Iteration:
- Reference specific parts: "the submit button"
- Be precise: "change padding to 24px" not "add more space"
- Ask for variants: "create hover and active states"
- Request alternatives: "show 3 different layouts"
-
name: Export and Integration description: Move v0 components to your codebase when_to_use: Using generated components implementation: |
Step 1: Export from v0
Click "Code" tab, then "Copy"
Or use CLI: npx v0 add <component-url>
Step 2: Set Up shadcn/ui (if not done)
npx shadcn-ui@latest init
Step 3: Add Required Components
v0 will tell you which components are needed
npx shadcn-ui@latest add button card input
Step 4: Create Component File
components/pricing-card.tsx
import { Button } from "@/components/ui/button" import { Card, CardContent, CardHeader } from "@/components/ui/card"
interface PricingCardProps { plan: string price: number features: string[] isPopular?: boolean onSelect: () => void }
export function PricingCard({ plan, price, features, isPopular = false, onSelect }: PricingCardProps) { // v0 generated code here, adapted with props return ( <Card className={isPopular ? "border-primary" : ""}> {/* ... */} </Card> ) }
Step 5: Customize for Your Design System
- Replace hardcoded colors with CSS variables
- Use your typography scale
- Match your spacing conventions
- Add your animation preferences
Step 6: Add Tests
import { render, screen } from "@testing-library/react" import { PricingCard } from "./pricing-card"
test("renders plan name", () => { render(<PricingCard plan="Pro" price={29} features={[]} onSelect={() => {}} />) expect(screen.getByText("Pro")).toBeInTheDocument() })
-
name: Complex Layouts description: Generate multi-component layouts when_to_use: Building full pages or sections implementation: |
Strategy: Build in Layers
Layer 1: Shell/Layout
"Create a dashboard layout with:
- Collapsible sidebar (icons only when collapsed)
- Top header with search and user menu
- Main content area with padding
- Mobile: bottom navigation instead of sidebar Use shadcn Sheet for mobile menu"
Layer 2: Major Sections
"Create a stats overview section with:
- 4 metric cards in a row (stack on mobile)
- Each card: icon, label, value, trend indicator
- Subtle hover effect Use shadcn Card"
Layer 3: Data Components
"Create a data table with:
- Sortable columns
- Row selection with checkboxes
- Pagination
- Empty state
- Loading skeleton Use shadcn Table and Skeleton"
Layer 4: Interactive Elements
"Create a filter bar with:
- Search input
- Date range picker
- Status dropdown (multi-select)
- Clear all button Use shadcn Popover, Calendar, Command"
Layer 5: Empty/Error States
"Create states for the table:
- Empty: illustration, message, CTA button
- Error: retry button, support link
- No results: clear filters suggestion"
Combine in Your Codebase:
// app/dashboard/page.tsx import { DashboardShell } from "@/components/dashboard-shell" import { StatsOverview } from "@/components/stats-overview" import { DataTable } from "@/components/data-table" import { FilterBar } from "@/components/filter-bar"
export default function Dashboard() { return ( <DashboardShell> <StatsOverview /> <FilterBar /> <DataTable /> </DashboardShell> ) }
-
name: Design System Alignment description: Match v0 output to your design system when_to_use: Consistent brand application implementation: |
Include Design Tokens in Prompts
Color System
"Use this color scheme:
- Primary: blue-600 (#2563eb)
- Secondary: slate-600
- Accent: amber-500
- Background: slate-50 (light) / slate-900 (dark)
- Text: slate-900 (light) / slate-50 (dark)"
Typography
"Typography:
- Headings: font-semibold, tracking-tight
- Body: text-base, text-slate-600
- Small: text-sm, text-slate-500
- Use Inter font family"
Spacing
"Spacing:
- Card padding: p-6
- Section gap: gap-8
- Inline spacing: gap-2
- Border radius: rounded-lg (default), rounded-full (avatars)"
Shadows
"Shadows:
- Cards: shadow-sm
- Dropdowns: shadow-lg
- Modals: shadow-xl
- Hover: shadow-md transition"
Motion
"Animations:
- Transitions: duration-200, ease-out
- Hover scale: scale-[1.02]
- Use Tailwind animate utilities"
After Export: CSS Variables
/* globals.css */ :root { --primary: 221.2 83.2% 53.3%; --primary-foreground: 210 40% 98%; --radius: 0.5rem; }
Component Customization
// Extend shadcn components const Button = React.forwardRef<...>(({ className, ...props }, ref) => ( <button className={cn( buttonVariants({ variant, size }), "font-semibold tracking-tight", // Your additions className )} ref={ref} {...props} /> ))
anti_patterns:
-
name: Vague Prompts description: "Make it look good" or "create a form" why_bad: | v0 guesses at requirements. Output needs more iteration. Inconsistent results. what_to_do_instead: | Be specific about:
- Exact components to use
- Layout and spacing
- States and interactions
- Accessibility requirements
-
name: Generating Entire Apps description: Trying to build full pages in one prompt why_bad: | Hard to iterate on parts. Complex prompts get confused. Can't reuse components. what_to_do_instead: | Build component by component. Generate reusable pieces. Compose in your codebase.
-
name: Copy-Paste Without Review description: Using generated code directly why_bad: | May have accessibility issues. Hardcoded values. Inconsistent with your codebase. what_to_do_instead: | Review for accessibility. Replace hardcoded values with props. Match your naming conventions. Add TypeScript types.
-
name: Ignoring Mobile description: Not specifying responsive behavior why_bad: | v0 defaults may not match needs. Breakpoints might be wrong. Touch targets too small. what_to_do_instead: | Always specify mobile behavior. Test at multiple breakpoints. Consider touch interactions.
handoffs:
-
trigger: "next.js|app router|routing" to: nextjs-app-router context: "Need to integrate v0 component in Next.js"
-
trigger: "tailwind|styling|css" to: tailwind context: "Need to customize v0 styling"
-
trigger: "accessibility|a11y|aria" to: accessibility-audit context: "Need to audit v0 generated code"