Next.js + shadcn/ui Builder & Migration Tool
Build production-grade Next.js applications or systematically migrate existing frontends to Next.js + shadcn/ui following strict design principles and best practices.
Overview
This skill handles two primary workflows:
Creating New Next.js Applications - Initialize projects with Next.js 15+ (App Router), shadcn/ui, and proper design system setup Migrating Existing Frontends - Analyze any frontend codebase (React, Vue, Angular, vanilla JS) and systematically convert to Next.js + shadcn/ui
Core Philosophy: 100% adherence to shadcn/ui design principles:
CSS variables for all theming (colors, spacing, typography) Standard shadcn/ui components only (no custom UI components) No hardcoded values (colors, spacing, fonts) Consistent design tokens across the application Mobile-first responsive design for all devices (phone, tablet, desktop) WCAG 2.1 Level AA accessibility compliance Best practices from https://ui.shadcn.com Workflow Decision Tree User Request ├─ Creating New Next.js App │ └─ Follow "Creating New Application" workflow (Phase 3 onwards) │ └─ Migrating Existing Codebase ├─ Phase 1: Codebase Analysis ├─ Phase 2: Migration Planning ├─ Phase 3: Next.js + shadcn Setup ├─ Phase 4: Systematic Conversion └─ Phase 5: Verification & Cleanup
High-Level Workflow for Migration Phase 1: Codebase Analysis
Automated analysis of existing frontend to understand scope and complexity.
Steps:
Framework and version detection Component inventory and categorization Hardcoded value detection (colors, spacing, custom components) Styling approach analysis (CSS, SCSS, CSS-in-JS, Tailwind, etc.) State management and routing pattern identification Generate comprehensive analysis report
Deliverables:
Framework analysis report Component inventory (JSON) Hardcoded values report Complexity assessment Phase 2: Migration Planning
Create systematic conversion plan with prioritized batches.
Steps:
Map existing components to shadcn/ui equivalents Identify components requiring custom development Organize conversion into batches (5-10 components per batch) Assess risk and complexity per batch Create detailed migration plan
Deliverables:
Component mapping table Batched conversion plan Risk assessment Estimated complexity per component Phase 3: Next.js + shadcn Setup
Initialize Next.js infrastructure alongside or replacing existing codebase.
Steps:
Check/install shadcn MCP server for documentation access Initialize Next.js 15+ with App Router and TypeScript Install and configure Tailwind CSS Run shadcn/ui initialization Set up CSS variables and design tokens Configure path aliases (@/) Install essential shadcn components Create design system documentation
Deliverables:
Configured Next.js project Design token system (CSS variables) Component library setup Path aliases configured Phase 4: Systematic Conversion
Convert components batch by batch with testing after each batch.
Steps:
Batch 1: Layout & Structure (Header, Footer, Layout wrappers) Batch 2: Simple UI Components (Buttons, Cards, Badges, Alerts) Batch 3: Form Components (Inputs, Selects, Checkboxes, Forms) Batch 4: Complex Components (Tables, Dialogs, Command Menus, Data visualizations) Batch 5: Styling Standardization (Remove hardcoded values, apply CSS variables) Batch 6: Pages & Routes (Convert pages, set up Next.js routing)
Per Batch Workflow:
Select 5-10 related components Use MCP to find appropriate shadcn components Convert components following shadcn patterns Replace hardcoded values with CSS variables Test functionality Verify visual consistency Move to next batch
Deliverables:
Migrated components (batch by batch) Updated styling with CSS variables Next.js App Router pages Passing tests per batch Phase 5: Verification & Cleanup
Final testing, optimization, and old code removal.
Steps:
Run full test suite Visual regression testing Responsive design testing (mobile, tablet, desktop) Performance audit Accessibility audit (WCAG 2.1 Level AA compliance) Remove old framework code Documentation updates Generate completion report
Deliverables:
Test results Responsive design verification report Performance metrics Accessibility audit report (WCAG 2.1 AA) Clean codebase Migration summary Phase 1: Codebase Analysis (Detailed Instructions) 1.1 Framework Detection
Run the automated analysis script:
python ./scripts/analyze-codebase.py /path/to/existing/codebase
This script will:
Detect framework (React, Vue, Angular, Svelte, vanilla JS, etc.) Identify framework version Detect build tool (Vite, Webpack, Parcel, etc.) Find package.json dependencies Map directory structure
Output: codebase-analysis.json with framework metadata
1.2 Component Inventory
The analysis script automatically generates a component inventory including:
Component name and file path Component type (functional, class, Vue SFC, etc.) Props/inputs State usage Child components External dependencies
Output: component-inventory.json
Example structure:
{ "components": [ { "name": "UserCard", "path": "src/components/UserCard.tsx", "type": "functional", "complexity": "simple", "shadcn_equivalent": "Card", "hardcoded_values": ["#3b82f6", "16px padding"], "dependencies": ["react", "styled-components"] } ] }
1.3 Hardcoded Value Detection
Run the detection script:
bash ./scripts/detect-hardcoded-values.sh /path/to/existing/codebase
This script detects:
Hardcoded colors: #hex, rgb(), rgba(), hsl(), color names Inline spacing: margin: 20px, padding: 1rem Custom font declarations: non-standard fonts Magic numbers: arbitrary values in components Inline styles: style={{...}} Non-standard patterns: CSS-in-JS, styled-components that should be Tailwind
Output: hardcoded-values-report.md with violations grouped by category
1.4 Generate Analysis Report
Run the report generator:
python ./scripts/generate-migration-report.py
This combines all analysis data into a comprehensive markdown report:
Output: migration-analysis-report.md
Frontend Migration Analysis Report
Executive Summary
[One-paragraph overview: framework, size, complexity]
Current State Analysis
- Framework: React 18.2.0
- Build Tool: Vite 4.3.0
- Component Count: 47 components
- Styling: styled-components + custom CSS
- State Management: Redux Toolkit
- Routing: React Router v6
Hardcoded Values Detected
- Colors: 142 instances across 34 files
- Spacing: 89 instances across 28 files
- Custom fonts: 3 non-standard fonts
- Inline styles: 67 instances
Component Categorization
- Simple (shadcn mapping exists): 28 components
- Moderate (requires adaptation): 13 components
- Complex (custom development needed): 6 components
Recommended Migration Plan
- Phase 3: Setup Next.js + shadcn infrastructure
- Phase 4.1: Convert layout components (Header, Footer, Layout)
- Phase 4.2: Convert simple UI (Button, Card, Badge → shadcn equivalents)
- Phase 4.3: Convert forms (Input, Select → shadcn/ui Form components)
- Phase 4.4: Convert complex components (DataTable, Charts)
- Phase 4.5: Styling standardization (CSS variables)
- Phase 4.6: Pages and routing
- Phase 5: Verification and cleanup
Estimated Effort
- Total Components: 47
- Batches: 9-10 batches
- Complexity: Moderate
Phase 2: Migration Planning (Detailed Instructions) 2.1 Component Mapping Strategy
Review the component-inventory.json and create a mapping table using the shadcn component reference.
VERY IMPORTANT: Use MCP to discover shadcn components
Before mapping, check if shadcn MCP server is available:
Check if MCP server is available
Try accessing https://ui.shadcn.com/docs/mcp
If MCP is not available, install it:
npx shadcn@latest mcp init --client claude
Use MCP to query available components:
"What shadcn components are available for buttons?" "Show me form components in shadcn" "What's the shadcn equivalent of a modal/dialog?" "Available data display components in shadcn"
Component Mapping Table Template:
Existing Component shadcn Equivalent Complexity Priority Notes CustomButton Button Low 1 Props mostly compatible Modal Dialog Medium 2 Different API, uses Radix DataTable Table + DataTable High 3 Requires custom hooks Dropdown DropdownMenu Low 1 Direct mapping DatePicker Calendar + Popover Medium 2 Composition pattern
Load framework-specific migration guide:
For React: Read ./references/react-to-nextjs.md For Vue: Read ./references/vue-to-nextjs.md For Angular: Read ./references/angular-to-nextjs.md For styling: Read ./references/styling-migration.md 2.2 Batch Organization
Organize components into batches following these principles:
Batching Strategy:
Group by type (layout, forms, data display, navigation) Simple to complex (start with easy wins) Dependency order (convert dependencies first) Batch size: 5-10 components per batch
Example Batch Plan:
Batch 1: Layout & Structure (Priority: Critical)
Header Footer MainLayout Container Sidebar
Batch 2: Simple UI Components (Priority: High)
Button → shadcn Button Card → shadcn Card Badge → shadcn Badge Alert → shadcn Alert Avatar → shadcn Avatar
Batch 3: Form Components (Priority: High)
Input → shadcn Input Select → shadcn Select Checkbox → shadcn Checkbox RadioGroup → shadcn RadioGroup Form validation → shadcn Form + react-hook-form
Batch 4: Navigation (Priority: Medium)
NavBar → shadcn NavigationMenu Breadcrumbs → shadcn Breadcrumb Tabs → shadcn Tabs Pagination → shadcn Pagination
Batch 5: Data Display (Priority: Medium)
Table → shadcn Table DataGrid → shadcn DataTable (with sorting, filtering) List → shadcn custom composition Accordion → shadcn Accordion
Batch 6: Overlays & Modals (Priority: Medium)
Modal → shadcn Dialog Tooltip → shadcn Tooltip Popover → shadcn Popover DropdownMenu → shadcn DropdownMenu
Batch 7: Complex Components (Priority: Low)
Charts → shadcn Charts (Recharts integration) Calendar/DatePicker → shadcn Calendar CommandPalette → shadcn Command DataVisualization → Custom with shadcn primitives
Batch 8: Styling Standardization (Priority: Critical)
Extract all hardcoded colors → CSS variables Convert spacing to Tailwind classes Standardize typography Apply theme system consistently
Batch 9: Pages & Routing (Priority: Critical)
Convert pages to Next.js App Router Set up layouts with Next.js layout.tsx Implement routing patterns Add loading and error states 2.3 Risk Assessment
For each batch, identify risks:
API Differences: Components with significantly different APIs Missing Features: Features in old components not in shadcn State Management: Complex state that needs refactoring Dependencies: External libraries that need replacement Custom Logic: Business logic tightly coupled to UI
Risk Mitigation:
Document API differences before conversion Create adapter/wrapper components when needed Write tests before migration Keep old components temporarily during transition 2.4 Create Detailed Migration Plan
Generate a detailed plan document: migration-plan.md
Next.js + shadcn Migration Plan
Project: [Project Name]
Date: [Current Date]
Estimated Timeline: [X batches]
Migration Strategy
Approach
- Incremental migration with parallel running old and new code
- Batch-based conversion (5-10 components per batch)
- Test after each batch before proceeding
- Feature flag new components during transition
Success Criteria
- All components use shadcn/ui or shadcn patterns
- Zero hardcoded colors/spacing (CSS variables only)
- 100% TypeScript coverage
- Passing test suite
- Lighthouse score >= 90
- No accessibility violations
Detailed Batch Plan
[Include all batches from 2.2 with specific components listed]
Timeline
Batch 1: Layout & Structure (Days 1-2) Batch 2: Simple UI (Days 3-4) [etc.]
Notes and Considerations
[Any special requirements, blockers, or dependencies]
Phase 3: Next.js + shadcn Setup (Detailed Instructions) 3.1 Check/Install shadcn MCP Server
CRITICAL: Always use MCP for shadcn component discovery
Check if MCP server is accessible:
Try to access documentation at https://ui.shadcn.com/docs/mcp Check if you can query shadcn components via MCP
If not available, install MCP server:
npx shadcn@latest mcp init --client claude
This enables:
Real-time shadcn documentation access Component discovery and search Block and chart template discovery Theme and design token reference
Using MCP during development:
"What components are available for [use case]?" "Show me the props for shadcn Button" "Available chart types in shadcn" "How to use shadcn Form with validation" 3.2 Initialize Next.js Project
Run the initialization script:
bash ./scripts/init-nextjs-shadcn.sh [project-name]
Or manually initialize:
Check Node.js version (18+ required)
node -v
Create Next.js project with App Router
npx create-next-app@latest [project-name] \ --typescript \ --tailwind \ --app \ --src-dir \ --import-alias "@/*" \ --no-turbopack
cd [project-name]
3.3 Install and Configure shadcn/ui
Initialize shadcn/ui
npx shadcn@latest init
Configuration prompts:
- TypeScript: Yes
- Style: Default
- Base color: Choose from slate/gray/zinc/neutral/stone
- CSS variables: Yes (CRITICAL - required for theming)
- Import alias: @/components
This creates:
components.json config file lib/utils.ts with cn() helper Updated tailwind.config.ts with shadcn theme CSS variables in app/globals.css 3.4 Configure Design Tokens (CSS Variables)
VERY IMPORTANT: All theming MUST use CSS variables
Color Format: OKLCH (Recommended)
This skill uses OKLCH (OKLab Lightness Chroma Hue) color space instead of HSL for better perceptual uniformity and color accuracy.
OKLCH Benefits:
Perceptually uniform (equal changes = equal perceived differences) Better gradient interpolation More predictable lightness Better for accessibility (more accurate contrast ratios)
Edit app/globals.css to define your design system:
@tailwind base; @tailwind components; @tailwind utilities;
@layer base { :root { --radius: 0.65rem;
/* Background - Pure white */
--background: 1 0 0;
--foreground: 0.141 0.005 285.823;
/* Card */
--card: 1 0 0;
--card-foreground: 0.141 0.005 285.823;
/* Popover */
--popover: 1 0 0;
--popover-foreground: 0.141 0.005 285.823;
/* Primary - Warm orange */
--primary: 0.646 0.222 41.116;
--primary-foreground: 0.98 0.016 73.684;
/* Secondary - Light purple-gray */
--secondary: 0.967 0.001 286.375;
--secondary-foreground: 0.21 0.006 285.885;
/* Muted - Subtle elements */
--muted: 0.967 0.001 286.375;
--muted-foreground: 0.552 0.016 285.938;
/* Accent */
--accent: 0.967 0.001 286.375;
--accent-foreground: 0.21 0.006 285.885;
/* Destructive - Red */
--destructive: 0.577 0.245 27.325;
/* Border and Input */
--border: 0.92 0.004 286.32;
--input: 0.92 0.004 286.32;
/* Focus ring */
--ring: 0.75 0.183 55.934;
/* Chart colors */
--chart-1: 0.837 0.128 66.29;
--chart-2: 0.705 0.213 47.604;
--chart-3: 0.646 0.222 41.116;
--chart-4: 0.553 0.195 38.402;
--chart-5: 0.47 0.157 37.304;
}
.dark { / Dark mode backgrounds / --background: 0.141 0.005 285.823; --foreground: 0.985 0 0;
/* Dark mode card */
--card: 0.21 0.006 285.885;
--card-foreground: 0.985 0 0;
/* Dark mode popover */
--popover: 0.21 0.006 285.885;
--popover-foreground: 0.985 0 0;
/* Dark mode primary - Brighter for contrast */
--primary: 0.705 0.213 47.604;
--primary-foreground: 0.98 0.016 73.684;
/* Dark mode secondary */
--secondary: 0.274 0.006 286.033;
--secondary-foreground: 0.985 0 0;
/* Dark mode muted */
--muted: 0.274 0.006 286.033;
--muted-foreground: 0.705 0.015 286.067;
/* Dark mode accent */
--accent: 0.274 0.006 286.033;
--accent-foreground: 0.985 0 0;
/* Dark mode destructive */
--destructive: 0.704 0.191 22.216;
/* Dark mode borders (with alpha) */
--border: 1 0 0 / 10%;
--input: 1 0 0 / 15%;
/* Dark mode focus ring */
--ring: 0.408 0.123 38.172;
/* Chart colors (consistent) */
--chart-1: 0.837 0.128 66.29;
--chart-2: 0.705 0.213 47.604;
--chart-3: 0.646 0.222 41.116;
--chart-4: 0.553 0.195 38.402;
--chart-5: 0.47 0.157 37.304;
} }
@layer base { * { @apply border-border; } body { @apply bg-background text-foreground; } }
Customizing for Migrated Project:
If migrating an existing app with a design system, extract existing colors and map to CSS variables:
Use the detection script to find existing colors
bash ./scripts/detect-hardcoded-values.sh /path/to/old/codebase
Map old colors to new CSS variables (OKLCH format)
Use https://oklch.com or https://colorjs.io to convert
Example:
Old: #FF6B35 (brand orange) → --primary: 0.646 0.222 41.116
Old: #3B82F6 (blue) → --primary: 0.630 0.213 255.5
Old: #10B981 (green) → --success: 0.710 0.180 165.4
3.5 Install Essential shadcn Components
Use MCP to discover which components you need!
Install core components:
Layout & Structure
npx shadcn@latest add card npx shadcn@latest add separator
Forms
npx shadcn@latest add button npx shadcn@latest add input npx shadcn@latest add label npx shadcn@latest add select npx shadcn@latest add checkbox npx shadcn@latest add radio-group npx shadcn@latest add form
Navigation
npx shadcn@latest add navigation-menu npx shadcn@latest add tabs npx shadcn@latest add breadcrumb
Feedback
npx shadcn@latest add alert npx shadcn@latest add toast npx shadcn@latest add dialog npx shadcn@latest add tooltip
Data Display
npx shadcn@latest add table npx shadcn@latest add badge npx shadcn@latest add avatar
Overlays
npx shadcn@latest add popover npx shadcn@latest add dropdown-menu npx shadcn@latest add sheet
Query MCP for additional components as needed during development.
3.6 Set Up Theme Provider (Dark Mode Support)
Install next-themes:
npm install next-themes
Create components/theme-provider.tsx:
"use client"
import * as React from "react" import { ThemeProvider as NextThemesProvider } from "next-themes" import { type ThemeProviderProps } from "next-themes/dist/types"
export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
return
Update app/layout.tsx:
import { ThemeProvider } from "@/components/theme-provider"
export default function RootLayout({ children }: { children: React.ReactNode }) { return (
3.7 Create Example Component
Create components/example-card.tsx demonstrating best practices:
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card" import { Button } from "@/components/ui/button"
export function ExampleCard() {
return (
Notice: No hardcoded colors, using CSS variables via Tailwind classes,
standard shadcn components, and proper typography scale.
Key Patterns Demonstrated:
Uses standard shadcn components (Card, Button) No hardcoded colors (uses text-muted-foreground) CSS variables automatically applied via Tailwind Semantic variants (outline, default) Proper component composition Phase 4: Systematic Conversion (Detailed Instructions) 4.1 Component Conversion Workflow
For each batch of 5-10 components:
Step 1: Review Components in Batch
Load the component files and understand:
Current functionality Props/API Styling approach State management Event handlers
Step 2: Query MCP for shadcn Equivalents
Before converting, use MCP:
"What's the shadcn component for [component type]?" "Show me shadcn [component] props and examples" "How to use shadcn [component] with [feature]?"
Step 3: Convert Component
Follow this pattern:
// OLD: Custom button with hardcoded styles const CustomButton = ({ children, onClick, variant = 'primary' }) => { const styles = { primary: { backgroundColor: '#3b82f6', // HARDCODED! color: '#ffffff', padding: '8px 16px', // HARDCODED! borderRadius: '6px' }, secondary: { backgroundColor: '#6b7280', color: '#ffffff', padding: '8px 16px', borderRadius: '6px' } }
return ( ) }
// NEW: shadcn Button with CSS variables import { Button } from "@/components/ui/button"
const CustomButton = ({ children, onClick, variant = 'default' }) => { return ( ) }
Conversion Checklist:
✅ Replace with shadcn component ✅ Remove all hardcoded colors ✅ Remove inline styles ✅ Use Tailwind classes only ✅ Use semantic variants (default, outline, destructive, etc.) ✅ Preserve all functionality ✅ TypeScript types properly defined
Step 4: Replace Hardcoded Values with CSS Variables
// OLD: Hardcoded spacing and colors