Make your AI a shadcn expert

Shadcn Button

React button for forms, dialogs, and toolbar actions. Built with TypeScript and Tailwind CSS for Next.js using Base UI — variants, sizes, and buttonVariants for links.

A button is the click that commits — submit, delete, open a dialog. It is a native button. For a link that only needs the look, use buttonVariants on an <a> — Base UI’s render would force role="button" onto the anchor. One primary per view; the rest stay outline, secondary, or ghost.

Scroll to load preview...

Looking for a neobrutalism version for shadcn?

Same button, thicker borders. The NeoBrutalism button is the kit if you want that look.

Usage

import { Button } from "@/components/ui/button"
<Button variant="outline">Save</Button>

variant is default, outline, secondary, ghost, destructive, or link. size is xs through lg, plus the icon sizes.

Composition

Button

buttonVariants is the class helper. Use it on an <a> or anything that should look like a button but is not one. Switch to Radix UI if you want render instead.

Size

xs in a chip, sm in a toolbar, lg for the main CTA. Pair each text size with the matching icon-* size.

Scroll to load preview...

Default

The solid primary. One per view — Save, Continue, Pay.

Scroll to load preview...

Outline

A border, no fill. The usual Cancel next to a primary.

Scroll to load preview...

Secondary

Filled but quiet. A second action that still needs weight.

Scroll to load preview...

Ghost

No chrome until hover. Toolbars, icon rows, overflow menus.

Scroll to load preview...

Destructive

The red one. Delete, remove, revoke — not a warning you can undo later.

Scroll to load preview...

Looks like a text link, still a button. For a real navigation, use buttonVariants on an <a>.

Scroll to load preview...

Icon

size="icon" (or icon-xs / icon-sm / icon-lg). Give it an aria-label.

Scroll to load preview...

With Icon

data-icon="inline-start" or inline-end so padding matches the reading direction.

Scroll to load preview...

Rounded

rounded-full on the button. Common for a lone icon.

Scroll to load preview...

Spinner

Put a Spinner in the label and disable the button. Same data-icon attributes.

Scroll to load preview...

Button Group

A Button Group for fused actions. Same stack as the rest of this page.

Scroll to load preview...

buttonVariants on an <a>. Do not render a Base UI Button as a link — it keeps role="button".

Scroll to load preview...

RTL

Wrap with DirectionProvider and dir="rtl". Keep data-icon="inline-start" / inline-end so icons flip with the text.

Scroll to load preview...

API

Prop

Type

Native button props (disabled, type, onClick) pass through.

Keyboard

KeyAction
Space / EnterActivate the focused button
TabMove to the next control

Notes

Name every icon button

aria-label="Submit" — a bare arrow reads as “button”. Same for size="icon-xs".

Put data-icon="inline-start" or inline-end on icons and Spinner so the padding matches.

With other components

Questions

Was this page helpful?

Sign in to leave feedback.