Required File Structure
Every submission requires exactly 2 files:
How it works: Our admin team will copy your files to the codebase, install any dependencies you list, and manually test the component. Once approved, your component gets published with you as the author.
1. Component File (ui/)
This is your core component that users will install. Place it in the ui/ folder.
"use client"
import { cn } from "@/lib/utils"
interface GlowButtonProps {
children: React.ReactNode
className?: string
variant?: "purple" | "blue" | "green"
}
export function GlowButton({
children,
className,
variant = "purple"
}: GlowButtonProps) {
const colors = {
purple: "bg-purple-600 hover:shadow-purple-500/50",
blue: "bg-blue-600 hover:shadow-blue-500/50",
green: "bg-green-600 hover:shadow-green-500/50",
}
return (
<button
className={cn(
"px-6 py-3 rounded-lg text-white font-medium",
"hover:shadow-[0_0_30px_rgba(0,0,0,0.3)]",
"transition-all duration-300",
colors[variant],
className
)}
>
{children}
</button>
)
}2. Preview File (preview/)
This page demonstrates your component in action. Shows admins and users how to use it.
import { GlowButton } from "@/components/ui/glow-button"
export default function PreviewPage() {
return (
<div className="min-h-screen flex flex-col items-center justify-center gap-8 bg-background p-8">
<h1 className="text-3xl font-bold">Glow Button</h1>
{/* Default variant */}
<GlowButton>Click Me</GlowButton>
{/* All variants */}
<div className="flex gap-4">
<GlowButton variant="purple">Purple</GlowButton>
<GlowButton variant="blue">Blue</GlowButton>
<GlowButton variant="green">Green</GlowButton>
</div>
</div>
)
}NPM Dependencies
If your component uses external packages like framer-motion,three, gsap, or @radix-ui, list them in the dependencies field.
npm i framer-motion three @react-three/fiber gsapAdmin will run this command before testing your component.
"use client"
import { useRef } from "react"
import { Canvas, useFrame } from "@react-three/fiber"
import * as THREE from "three"
function Sphere() {
const meshRef = useRef<THREE.Mesh>(null)
useFrame((state) => {
if (meshRef.current) {
meshRef.current.rotation.y += 0.01
}
})
return (
<mesh ref={meshRef}>
<sphereGeometry args={[1, 32, 32]} />
<meshStandardMaterial
color="#a855f7"
metalness={0.8}
roughness={0.2}
/>
</mesh>
)
}
export function LiquidSphere() {
return (
<div className="w-full h-[400px]">
<Canvas camera={{ position: [0, 0, 3] }}>
<ambientLight intensity={0.5} />
<pointLight position={[10, 10, 10]} />
<Sphere />
</Canvas>
</div>
)
}Styling Guidelines
Use Tailwind CSS
All Tailwind utility classes are available
Use cn() for conditional classes
Import from @/lib/utils: cn("base-class", condition && "active")
Use theme CSS variables
Colors like bg-background, text-foreground, text-muted-foreground
Use Lucide React icons
Import from lucide-react: import { Sparkles } from 'lucide-react'
What Works
These are available and will work in your components:
React Hooks
useState, useEffect, useRef, etc.
Tailwind CSS
All utility classes
Lucide Icons
Icon library
cn() utility
Class merging
TypeScript
Full type support
framer-motion
List as dependency
Three.js
List as dependency
GSAP
List as dependency
These won't work:
API calls
No fetch, axios, or server calls
Environment variables
No process.env access
Database access
No Prisma or DB queries
Server components
No async components
Complete Examples
1. Interactive Button with State
"use client"
import { useState } from "react"
import { cn } from "@/lib/utils"
import { Sparkles } from "lucide-react"
interface PulseButtonProps {
children: React.ReactNode
className?: string
}
export function PulseButton({ children, className }: PulseButtonProps) {
const [isPulsing, setIsPulsing] = useState(false)
return (
<button
className={cn(
"relative px-6 py-3 rounded-lg",
"bg-gradient-to-r from-purple-600 to-pink-600",
"text-white font-medium",
"hover:scale-105 transition-transform",
isPulsing && "animate-pulse",
className
)}
onClick={() => {
setIsPulsing(true)
setTimeout(() => setIsPulsing(false), 1000)
}}
>
<Sparkles className="inline-block w-4 h-4 mr-2" />
{children}
</button>
)
}2. Animated Card (requires framer-motion)
"use client"
import { motion } from "framer-motion"
import { cn } from "@/lib/utils"
interface FloatCardProps {
title: string
children: React.ReactNode
className?: string
}
export function FloatCard({ title, children, className }: FloatCardProps) {
return (
<motion.div
initial={{ y: 20, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
whileHover={{ y: -5, scale: 1.02 }}
transition={{ type: "spring", stiffness: 300 }}
className={cn(
"p-6 rounded-xl border bg-card",
"shadow-lg hover:shadow-xl transition-shadow",
className
)}
>
<h3 className="text-xl font-bold mb-2">{title}</h3>
{children}
</motion.div>
)
}3. 3D Element (requires three, @react-three/fiber)
"use client"
import { useRef } from "react"
import { Canvas, useFrame } from "@react-three/fiber"
import * as THREE from "three"
function Cube() {
const meshRef = useRef<THREE.Mesh>(null)
useFrame(() => {
if (meshRef.current) {
meshRef.current.rotation.x += 0.01
meshRef.current.rotation.y += 0.01
}
})
return (
<mesh ref={meshRef}>
<boxGeometry args={[1.5, 1.5, 1.5]} />
<meshNormalMaterial />
</mesh>
)
}
export function SpinningCube() {
return (
<div className="w-full h-[300px] rounded-lg overflow-hidden">
<Canvas camera={{ position: [0, 0, 4] }}>
<ambientLight intensity={0.5} />
<Cube />
</Canvas>
</div>
)
}Ready to Submit?
Create your two files, list any dependencies, and submit. Our team manually tests every component for quality.