Shadcn Button Components

Displays a button or a component that looks like a button. Every button example is built to work with both Radix UI and Base UI. Browse our collection of 27 Shadcn Button variants.

Unlock premium components
Get full control of shadcn/ui components, blocks and instances, including future additions.

Explore Shadcn Blocks

Ready-made page sections built with the same components.

View all blocks

Shadcn Button Component

The Shadcn Button is the most used interactive element in any interface. It submits forms, opens menus and dialogs, confirms destructive actions and starts every important flow in your product, so a consistent, accessible button is the foundation the rest of your UI is built on.

Beyond the usual primary, secondary and destructive styles, this shadcn button collection focuses on the patterns that normally take extra work: loading spinners, copy to clipboard feedback, split buttons with a dropdown, quantity steppers and social login buttons for Google, GitHub, X and Facebook. Built with shadcn/ui, React and Tailwind CSS, each example runs in Radix UI or Base UI projects and supports dark mode.

What is the Shadcn Button Component?

The shadcn/ui button is a native <button> element with a set of styles defined by class-variance-authority. You pick a look with the variant prop (default, secondary, outline, ghost, destructive or link) and a size with the size prop, including square sizes for icon only buttons. The exported buttonVariants function returns the same classes, so you can style a link or any other element to look like a button.

Use a button for actions: saving, deleting, opening something or running a command. When the action only navigates to another page, render a link with asChild so the markup stays semantic. For an on and off state that stays pressed, use a Toggle instead, and for several related actions sitting side by side, use a Button Group.

Anatomy of the Shadcn Button

PartDescription
ButtonThe component itself. Accepts every native button prop plus variant, size and asChild, and exposes data-variant and data-size attributes for styling.
buttonVariantsThe cva helper that generates the button classes. Call it with a variant and size to apply button styles to a Link or any other element.

27 Shadcn Button Variants

Each button variant listed here is previewed live at the top of this page, together with its source code and install command.

  • Basic, secondary and destructive: The default primary button, a Cancel and Save pair using the secondary variant, and a Delete button with a trash icon for destructive actions.
  • Loading states: A disabled button with a spinning loader next to the label, and a click to load button that overlays the spinner so the width never changes.
  • Counts, badges and shortcuts: Buttons with a message count, a keyboard shortcut hint, a star or like counter, and a notification bell with a badge that clears on click.
  • Icon and avatar buttons: Square and rounded icon buttons, an icon button with a tooltip, a button that hides its label on small screens, and a pill button with a profile image.
  • Animated state buttons: A copy to clipboard button that swaps to a check mark, and a light and dark mode switch that animates between a sun and a moon icon.
  • Button groups: Vertical plus and minus controls, a search input with a button, a quantity stepper, previous and next pairs, and a group with separators.
  • Split buttons: A main action joined to a dropdown trigger, including a merge button that lets users pick the merge strategy from a radio list.
  • Social login: Icon only, outline and brand colored buttons for Google, X, Facebook and GitHub sign in.

How to Install the Shadcn Button Component

Set up shadcn/ui in your project if you have not already, then add the Shadcn UI Kit registry to your components.json once:

{
  "registries": {
    "@shadcnuikit": "https://shadcnuikit.com/r/{name}.json"
  }
}

Then install a button variant by its name:

npx shadcn@latest add @shadcnuikit/button1

The same command works with pnpm dlx, yarn dlx and bunx --bun. Each variant has a copy button for every package manager, and the code is added to your project as plain React and Tailwind CSS that you can edit freely.

How to Use the Shadcn Button Component

Import Button from your components/ui folder and choose a variant and size. Icons placed inside the button are sized automatically, and asChild renders your own element, such as a Next.js Link, with button styles.

import Link from "next/link"
import { PlusIcon, TrashIcon } from "lucide-react"

import { Button } from "@/components/ui/button"

export function Actions() {
  return (
    <div className="flex items-center gap-2">
      <Button>Save changes</Button>
      <Button variant="outline">Cancel</Button>
      <Button variant="destructive">
        <TrashIcon />
        Delete
      </Button>
      <Button variant="ghost" size="icon" aria-label="Add item">
        <PlusIcon />
      </Button>
      <Button variant="link" asChild>
        <Link href="/pricing">View pricing</Link>
      </Button>
    </div>
  )
}

Why Use the Shadcn Button Component

  • One component, many looks: Six visual variants and eight sizes cover primary, secondary, quiet and destructive actions without writing new styles.
  • Semantic by default: It renders a real button element, so keyboard activation, focus and form submission work without extra code.
  • Polymorphic with asChild: Apply button styles to links and other elements while keeping the correct HTML for navigation.
  • Theme aware: Colors come from CSS variables such as primary and destructive, so buttons follow your palette and dark mode automatically.
  • Easy to extend: Add a variant or size in one place and every button in the project can use it.

Common Button Use Cases

  • Form actions: Submit, save and cancel buttons at the bottom of forms and settings pages.
  • Calls to action: Sign up, start trial and download buttons on landing and pricing pages.
  • Destructive actions: Delete and remove buttons, usually followed by a confirmation dialog.
  • Toolbars: Compact icon buttons for editing, sharing, copying and printing in dashboards and editors.
  • Authentication: Social login buttons for Google, GitHub, X and Facebook on sign in pages.
  • Menu and dialog triggers: Buttons that open dropdown menus, popovers, sheets and drawers.

Customizing the Shadcn Button

Pass a className to change a single button, or edit buttonVariants in components/ui/button.tsx to change every button at once. Colors are defined with theme tokens like bg-primary and text-primary-foreground, so updating the CSS variables in your theme restyles all buttons. You can generate a matching palette with the free Theme Generator.

For example, a softer subtle variant only needs one extra line in the variant map:

const buttonVariants = cva("...", {
  variants: {
    variant: {
      // ...existing variants
      subtle: "bg-primary/10 text-primary hover:bg-primary/20",
    },
  },
})

<Button variant="subtle">Publish</Button>

Button Accessibility and Keyboard Support

Because the component renders a native button, it is focusable, can be activated from the keyboard and is announced as a button by screen readers. Icon only buttons have no visible text, so always give them an aria-label and mark the icon with aria-hidden="true", as most icon variants on this page do.

Use the disabled attribute during loading so the action cannot run twice, and keep a visible label or a screen reader text next to the spinner. The focus ring uses the ring color from your theme, so keep enough contrast between it and the background.

KeyAction
EnterActivates the focused button.
SpaceActivates the focused button.
TabMoves focus to the next focusable element.
ShiftTabMoves focus to the previous focusable element.

Button Best Practices

  • Use one primary button per view and give secondary actions the outline, secondary or ghost variant.
  • Write labels as verbs that describe the result, such as Save changes or Delete project, instead of OK.
  • Set type="button" on buttons inside a form that should not submit it.
  • Show a loading state and disable the button while an async action is running.
  • Use asChild with a link for navigation instead of calling the router from an onClick handler.
  • Ask for confirmation before destructive actions with an Alert Dialog.

Components Related to Button

Shadcn Button FAQ

Add the asChild prop and place a Next.js Link or an anchor inside the Button. The child is rendered with button styles while keeping link semantics. You can also call buttonVariants() to get the classes and pass them to the link directly.

Keep a loading flag in state, set disabled while it is true and render a spinner icon with the animate-spin class inside the button. To avoid a width change, hide the label with a transparent text color and position the spinner absolutely on top of it.

Open components/ui/button.tsx and add a new key to the variant or size object inside buttonVariants. TypeScript picks it up automatically, so you can use it with the variant or size prop right away.

Use size="icon" or one of the icon sizes, add an aria-label that describes the action and set aria-hidden="true" on the icon. Adding a tooltip also helps sighted users understand what the button does.

Put the main Button and a second icon Button with a chevron inside a ButtonGroup. Wrap the chevron button in DropdownMenuTrigger with asChild and set align="end" on DropdownMenuContent so the menu lines up with the right edge of the group. The Follow split button on this page is built this way, while the merge button joins two plain buttons with rounded-none and first:rounded-s-md and last:rounded-e-md classes.

Looking for something else? Browse all shadcn/ui components or ready-made UI blocks built with them.