Write, Run & Share shadcn code online using OneCompiler's shadcn online editor for free. It's one of the robust, feature-rich online editors for shadcn. Getting started with the OneCompiler's shadcn online editor is really simple and pretty fast. The editor shows sample boilerplate code when you choose language as 'shadcn' and start writing code to learn and test online without worrying about tedious process of installation.
shadcn/ui isn't a package you install and import. It's a set of components you copy into your own project and keep, so you can edit them freely. The components are built on Radix UI for behavior and accessibility, and styled with Tailwind CSS. A small cn helper merges class names, and cva defines style variants. The playground loads the Tailwind runtime, so utility classes work right away.
cn combines clsx (conditional class names) with tailwind-merge (which resolves conflicting Tailwind classes so the last one wins). Nearly every component uses it.
import { clsx } from 'clsx';
import { twMerge } from 'tailwind-merge';
function cn(...inputs) {
return twMerge(clsx(inputs));
}
// later: cn('px-2', condition && 'px-4') -> 'px-4'
cva describes a base set of classes plus named variants. The component reads the chosen variant and passes the result to cn.
import { cva } from 'class-variance-authority';
const button = cva('inline-flex items-center rounded-md text-sm font-medium h-10 px-4', {
variants: {
variant: {
default: 'bg-slate-900 text-white hover:bg-slate-800',
outline: 'border border-slate-300 hover:bg-slate-100',
},
},
defaultVariants: { variant: 'default' },
});
function Button({ className, variant, ...props }) {
return <button className={cn(button({ variant }), className)} {...props} />;
}
Radix's Slot lets a component render as a different element while keeping its styles. Pass asChild and the styles land on the child you provide, like an anchor instead of a button.
import { Slot } from '@radix-ui/react-slot';
function Button({ asChild, className, ...props }) {
const Comp = asChild ? Slot : 'button';
return <Comp className={cn(button(), className)} {...props} />;
}
// renders a styled link:
<Button asChild>
<a href="/docs">Docs</a>
</Button>
Because components accept a className, you tweak any instance with utility classes. tailwind-merge keeps the override clean when classes overlap.
<Button className="w-full">Full width</Button>
<Button variant="outline" className="text-red-600 border-red-300">Danger</Button>
A "card" in shadcn is just a few divs with Tailwind classes that you wrap into a component. Nothing special is imported, so you can shape it however you like.
function Card({ children }) {
return (
<div className="rounded-lg border border-slate-200 bg-white p-6 shadow-sm">
{children}
</div>
);
}
<Card>
<h3 className="text-lg font-semibold">Title</h3>
<p className="text-slate-600">Some content inside the card.</p>
</Card>