The Problem with AI + Shadcn UI
Shadcn UI is fantastic for human developers — you copy components, paste them into your project, and customize as needed. But when AI tools like Claude Code or Cursor generate UI code, they face a critical challenge: how do you ensure consistency across hundreds of generated components?
AI can hallucinate color values, spacing, and styling patterns that don't match your design system. One component might use bg-blue-500, another bg-indigo-600, and a third #4F46E5 — all intended to be your "primary" color.
FramingUI: The Missing Bridge
FramingUI solves this by forking shadcn UI and integrating design tokens directly into every component. Instead of arbitrary Tailwind classes, every style references a semantic token:
// ❌ Shadcn UI (original)
<button className="bg-blue-500 hover:bg-blue-600 text-white">
Click me
</button>
// ✅ FramingUI (token-powered)
<Button variant="default">
Click me
</Button>
// Under the hood:
// bg-[var(--tekton-bg-primary)]
// hover:bg-[var(--tekton-bg-primary)]/90
Real-World Example: Button Component
Here's how FramingUI's Button component uses tokens:
import { Button } from '@framingui/ui';
function LoginForm() {
return (
<div className="space-y-[var(--tekton-spacing-4)]">
<Button variant="default">Sign In</Button>
<Button variant="outline">Create Account</Button>
<Button variant="destructive">Delete</Button>
</div>
);
}
Every button automatically inherits your theme's colors, spacing, and border radius — zero hardcoded values.
How Design Tokens Prevent AI Hallucination
When AI generates code using FramingUI, it can't hallucinate colors because:
- Single source of truth: All colors come from
var(--tekton-*)tokens - Semantic naming:
--tekton-bg-primaryis unambiguous - OKLCH foundation: Colors are perceptually uniform, ensuring consistent brightness
Example: AI-Generated Card
import { Card, CardHeader, CardTitle, CardDescription, CardContent } from '@framingui/ui';
// AI-generated component using FramingUI
function ProductCard({ title, description, price }: ProductCardProps) {
return (
<Card>
<CardHeader>
<CardTitle>{title}</CardTitle>
<CardDescription>{description}</CardDescription>
</CardHeader>
<CardContent>
<p className="text-2xl font-bold text-[var(--tekton-bg-primary)]">
${price}
</p>
</CardContent>
</Card>
);
}
Notice how the AI uses tokens (var(--tekton-bg-primary)) instead of guessing text-blue-600 or #3B82F6.
OKLCH: The Secret Sauce
FramingUI uses OKLCH color space for design tokens, which provides:
- Perceptual uniformity: L=0.5 looks equally bright across all hues
- Wider gamut: Access to more vibrant colors than sRGB
- WCAG compliance: Easier to hit AA/AAA contrast ratios
Traditional color spaces like HSL fail here — hsl(220, 100%, 50%) (blue) looks darker than hsl(60, 100%, 50%) (yellow) despite both having 50% lightness.
Integration with AI Tools
Cursor IDE Setup
# Install FramingUI
pnpm add @framingui/ui @framingui/core
# Generate design tokens from your brand color
npx framingui generate --color "#FF6B35"
Then add this to your Cursor rules (.cursorrules):
When generating UI components:
- Always import from @framingui/ui
- Use var(--tekton-*) tokens for colors, spacing, and radius
- Never hardcode color values or spacing
Claude Code Setup
Create a .claude/skills/framingui.md file:
## FramingUI Component Library
Import components from @framingui/ui:
- Button, Input, Card, Form, Dialog, etc.
Design tokens (use these instead of Tailwind colors):
- Colors: var(--tekton-bg-primary), var(--tekton-bg-secondary)
- Spacing: var(--tekton-spacing-2), var(--tekton-spacing-4)
- Radius: var(--tekton-radius-md), var(--tekton-radius-lg)
Migration from Shadcn UI
Already using shadcn UI? FramingUI is a drop-in replacement:
// Before (shadcn)
import { Button } from '@/components/ui/button';
// After (FramingUI)
import { Button } from '@framingui/ui';
// Same API, token-powered internals
Next Steps
- Try the playground: Visit framingui.com to generate your design tokens
- Install FramingUI:
pnpm add @framingui/ui - Configure your AI: Add FramingUI rules to Cursor or Claude Code
- Generate UI: Let AI create components with 0% hallucination
FramingUI gives AI the constraints it needs to generate consistent, production-ready UI — bridging the gap between shadcn UI's flexibility and AI's need for structure.