ShadCN/UI
LogicStamp Context provides specialized support for ShadCN/UI, a popular component library built on Radix UI and Tailwind CSS.
ShadCN Detection
LogicStamp automatically detects ShadCN/UI usage by:
- Component imports: Detects imports from
@/components/ui/*,~/components/ui/*, or relativecomponents/ui/*paths - Import aliases: Tracks aliased imports (e.g.,
import { Button as UIPrimaryButton }) and maps them to canonical component names - ShadCN components: Recognizes ShadCN component names and patterns
- Component structure: Identifies ShadCN's compound component patterns
- Usage frequency: Ranks components by actual usage count (imports + JSX usage), not just alphabetically
- Tailwind integration: Extracts Tailwind classes used with ShadCN components
What Gets Extracted
ShadCN Components
All ShadCN/UI components are detected and extracted:
import { Button } from '@/components/ui/button';
import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card';
import { Dialog, DialogTrigger, DialogContent } from '@/components/ui/dialog';
function MyComponent() {
return (
<Card>
<CardHeader>
<CardTitle>Title</CardTitle>
</CardHeader>
<CardContent>
<Button>Click me</Button>
<Dialog>
<DialogTrigger>Open</DialogTrigger>
<DialogContent>Content</DialogContent>
</Dialog>
</CardContent>
</Card>
);
}Detected components include:
Form Components
Button,Input,Label,TextareaCheckbox,RadioGroup,SelectSwitch,Slider,ToggleForm,FormField,FormItem,FormLabel,FormMessage
Layout Components
Card,CardHeader,CardTitle,CardDescription,CardContent,CardFooterSeparator,AspectRatioScrollArea,ScrollBar
Overlay Components
Dialog,DialogTrigger,DialogContent,DialogHeader,DialogTitle,DialogDescription,DialogFooterAlertDialog(all variants)Popover,PopoverTrigger,PopoverContentTooltip,HoverCardSheet,SheetTrigger,SheetContent
Navigation Components
DropdownMenu(all variants)ContextMenu(all variants)Menubar(all variants)NavigationMenu(all variants)Breadcrumbs
Data Display
Table,TableHeader,TableBody,TableRow,TableCellBadge,Avatar,AvatarImage,AvatarFallbackProgress,SkeletonCalendar,DatePicker
Feedback
Alert,AlertTitle,AlertDescriptionToast,ToasterCommand,CommandDialog,CommandInput,CommandList,CommandItem
Component Ranking:
Components are ranked by usage frequency (most used first), then alphabetically when tied. Up to 30 components are returned to keep context bundles focused while accommodating ShadCN's composable nature.
How ranking works: Each component occurrence (imports + JSX usage) increments its count. Components are sorted by count (descending), then alphabetically when tied. Only the top 30 most frequently used components are included. See Component Ranking and Limits for detailed explanation.
Component Variants
ShadCN's variant system is detected:
import { Button } from '@/components/ui/button';
import { Card } from '@/components/ui/card';
import { cn } from '@/lib/utils';
function Buttons() {
return (
<>
<Button variant="default">Default</Button>
<Button variant="destructive">Delete</Button>
<Button variant="outline">Outline</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="link">Link</Button>
<Button size="sm">Small</Button>
<Button size="lg">Large</Button>
<Card variant="custom-elevated">Custom Card</Card>
</>
);
}Extracted:
- Variant prop values (filtered for known components like Button, Badge, Alert)
- Card variants accept custom values (since ShadCN Card doesn't ship with variants)
- Size prop values
- Component composition patterns
Note: Button, Badge, and Alert variants are filtered to known values, while Card variants accept any custom value since ShadCN Card components are frequently extended with custom variants.
Compound Components
ShadCN's compound component pattern is recognized:
import {
DropdownMenu,
DropdownMenuTrigger,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
} from '@/components/ui/dropdown-menu';
function Menu() {
return (
<DropdownMenu>
<DropdownMenuTrigger>Open</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem>Item 1</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem>Item 2</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
}Extracted:
- Parent-child component relationships
- Component composition hierarchy
- Compound component usage patterns
Style Extraction
Style output shape: ShadCN-specific fields live under style.styleSources.shadcnUI (components, variants, sizes, features). Default --style-mode lean keeps features only (drops components, variants, and sizes). Tailwind classes are still reported separately under style.styleSources.tailwind when present. See UIF contracts and Style mode: lean vs full.
ShadCN components are analyzed for their Tailwind styling:
import { Card } from '@/components/ui/card';
function MyCard() {
return (
<Card className="w-full max-w-md shadow-lg">
<CardContent className="p-6">
Content
</CardContent>
</Card>
);
}Extracted style information:
- Tailwind classes applied to ShadCN components
- Custom className overrides
- Responsive design patterns
- Color and spacing usage
ShadCN-Specific Features
Component Library Detection
LogicStamp identifies when ShadCN is in use and merges that with Tailwind (and other sources) in style.summary.sources.
Example (--style-mode full):
{
"style": {
"styleSources": {
"shadcnUI": {
"components": ["Button", "Card", "Dialog"],
"variants": {
"Button": ["default", "outline"]
},
"sizes": ["default", "sm"],
"features": {
"usesTheme": true,
"usesIcons": true,
"usesForm": false,
"componentDensity": "medium"
}
}
},
"summary": {
"mode": "full",
"sources": ["shadcn", "tailwind"]
}
}
}Example (--style-mode lean, default):
{
"style": {
"styleSources": {
"shadcnUI": {
"features": {
"usesTheme": true,
"usesIcons": true,
"usesForm": false,
"componentDensity": "medium"
}
}
},
"summary": {
"mode": "lean",
"sources": ["shadcn", "tailwind"],
"fullModeBytes": 1750
}
}
}Form Integration
ShadCN's form components with React Hook Form are detected:
import { useForm } from 'react-hook-form';
import { Form, FormField, FormItem, FormLabel, FormControl } from '@/components/ui/form';
import { Input } from '@/components/ui/input';
function MyForm() {
const form = useForm();
return (
<Form {...form}>
<FormField
control={form.control}
name="email"
render={({ field }) => (
<FormItem>
<FormLabel>Email</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
</FormItem>
)}
/>
</Form>
);
}Extracted:
- Form component usage
- Form field relationships
- React Hook Form integration (
useForm,Controller,FormProvider)
Theme Integration
ShadCN's theme support is detected through multiple patterns:
import { ThemeProvider } from '@/components/theme-provider';
// or
import { ThemeProvider } from 'next-themes';
import { useTheme } from 'next-themes';
import { Button } from '@/components/ui/button';
function App() {
const { theme } = useTheme();
return (
<ThemeProvider>
<Button className="dark:bg-gray-900">Toggle</Button>
</ThemeProvider>
);
}Extracted:
useTheme()hook usageThemeProviderimports (detected from various sources)- Theme-related Tailwind classes (
dark:,theme-)
Usage
# Extract ShadCN components and styles (lean style output by default)
stamp context --include-style
# Or use the style command
stamp context style
# Include shadcnUI components/variants/sizes arrays in style JSON
stamp context style --style-mode fullShadCN Project Structure
LogicStamp recognizes ShadCN's typical structure:
my-app/
components/
ui/ # ShadCN components
button.tsx
card.tsx
dialog.tsx
lib/
utils.ts # cn() utility
app/ # Next.js App Router
page.tsxBest Practices
- Use ShadCN components: Import from
@/components/ui/*for detection - Import aliases: Aliased imports are supported (e.g.,
import { Button as UIPrimaryButton }) and will be correctly mapped to canonical component names - Extend components: Customize ShadCN components while maintaining structure
- Use variants: Leverage ShadCN's variant system for consistency
- Custom Card variants: Card components accept custom variants since ShadCN Card doesn't ship with variants
- Combine with Tailwind: Use Tailwind utilities alongside ShadCN components
- Form patterns: Use ShadCN's form components with React Hook Form
- Component ranking: Components are ranked by usage frequency, making it clear which components dominate your files
Common Patterns
Card with ShadCN
import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card';
function UserCard({ user }: { user: User }) {
return (
<Card className="w-full">
<CardHeader>
<CardTitle>{user.name}</CardTitle>
</CardHeader>
<CardContent>
<p>{user.email}</p>
</CardContent>
</Card>
);
}Dialog Pattern
import {
Dialog,
DialogTrigger,
DialogContent,
DialogHeader,
DialogTitle,
DialogDescription,
} from '@/components/ui/dialog';
function EditDialog() {
return (
<Dialog>
<DialogTrigger asChild>
<Button>Edit</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Edit Item</DialogTitle>
<DialogDescription>Make changes to the item.</DialogDescription>
</DialogHeader>
{/* Form content */}
</DialogContent>
</Dialog>
);
}Error Handling
The ShadCN extractor is designed to be robust and will never crash the CLI, even when encountering:
- Malformed JSX: Invalid or unclosed tags are handled gracefully
- Parse errors: AST parsing failures return empty results
- Invalid imports: Malformed import declarations are skipped
- AST traversal errors: Complex or malformed TypeScript that causes AST parsing issues falls back gracefully
- Feature detection errors: Failures in form/theme/icon detection return partial results
All error handling is silent by default. To enable debug logging for troubleshooting, set the LOGICSTAMP_DEBUG=1 environment variable:
LOGICSTAMP_DEBUG=1 stamp context --include-styleThis will output error messages to help identify problematic files or expressions:
[LogicStamp][DEBUG] shadcn.extractShadcnUI error: { filePath: '/path/to/file.tsx', error: 'Cannot read property \'getText\' of undefined' }
Best Practices
- Don't worry about missing imports: If a component imports ShadCN components that don't exist, the extractor will skip them and continue
- Check debug logs when issues occur: Enable
LOGICSTAMP_DEBUG=1if you suspect extraction problems - Expect partial results: Some extraction failures are normal (e.g., dynamically imported components can't be statically analyzed)
Limitations
- Custom ShadCN component modifications may not be fully detected
- Component variants defined in
components.jsonare not read - Dynamic component imports may not be tracked
- ShadCN CLI-generated components are detected but customization may not be captured
- Default import aliases (e.g.,
import PrimaryButton from '@/components/ui/button') are not recognized - use named imports instead - Component density is based on distinct component count, not total JSX usage count
Related Documentation
- Radix UI Support - ShadCN is built on Radix UI
- Tailwind CSS Support - ShadCN uses Tailwind for styling
- Style Extraction - Complete style extraction guide
- React Support - React component patterns
Next Steps
Explore other UI frameworks or learn about style metadata extraction.