Button

Purpose and Scope

The Button page documents the ARIA-backed shadcn/ui button as a copied component, not as a hidden package widget. The official component page describes it as a control that displays a button or something that looks like a button, and the surrounding docs show how this idea extends into groups, icons, loading states, rounded buttons, and right-to-left layouts. The practical goal is to help a developer install the component, understand which styling decisions are encoded by the registry, and choose the correct semantic element when an action looks similar to a link.

Sources: apps/v4/content/docs/components/aria/button.mdx, apps/v4/content/docs/components/aria/button-group.mdx

The important distinction in this component family is that visual styling and semantic behavior are not always the same thing. A real action should use the Button component, while navigation should normally remain a normal anchor styled with the helper recommended by the docs. This matters because the React Aria Button behavior applies a button role, and that can override link semantics on anchors. Treat Button as the action primitive, then use composition utilities when a link must share the same visual language.

Sources: apps/v4/content/docs/components/aria/button.mdx

Relevant Source Files

  • apps/v4/content/docs/components/aria/button.mdx - Primary Button documentation, including installation, usage, cursor guidance, variants, icon and spinner examples, link guidance, RTL preview, and the beginning of the API reference.
  • apps/v4/content/docs/components/aria/button-group.mdx - Companion Button Group documentation covering grouped actions, separators, text, inputs, orientation, nested groups, dropdown and select composition, accessibility notes, RTL, and the ButtonGroup API reference.
  • apps/v4/content/docs/changelog/2024-08-npx-shadcn-init.mdx - CLI rewrite context showing that components are installed with the shadcn command, components can ship dependencies, framework detection exists, and aliases are configured in components.json.
  • apps/v4/content/docs/changelog/2025-04-shadcn-2-5.mdx - Registry installation context for resolve-anywhere behavior and multi-pass import and alias resolution.
  • apps/v4/content/docs/changelog/2025-12-shadcn-create.mdx - Preset and style context explaining why button code can change with library, spacing, fonts, icons, and visual style choices.
  • apps/v4/content/docs/changelog/2026-04-shadcn-apply.mdx - Existing-project preset context showing that a project can reapply presets while keeping current base and RTL settings.

Installation and Setup Flow

Install Button through the command tab when your project already has shadcn/ui configured. The docs use the current package invocation and install only the component requested by name. For manual installation, the page tells you to install the React Aria dependency, copy the generated component source into the local user interface folder, and update imports for your project layout. This reflects the repository philosophy: the component becomes your code, so later edits to spacing, variants, or behavior happen in the application rather than behind a package boundary.

Sources: apps/v4/content/docs/components/aria/button.mdx

npx shadcn@latest add button
npm install react-aria-components

Button Group follows the same pattern but uses a separate registry item. Install it when related actions need a shared container, consistent spacing, separators, or mixed controls such as inputs and dropdown menus. The Button Group manual path also requires React Aria components and places the source in the local components folder. In practice, install Button first when you only need a single action, then add Button Group when repeated buttons must read as one toolbar-like unit or when a split action needs a primary control plus an adjacent menu trigger.

Sources: apps/v4/content/docs/components/aria/button-group.mdx

npx shadcn@latest add button-group

The changelog entries explain why installation is framed around a registry-aware command rather than a fixed package import. The rewritten CLI can add components and their dependencies, update existing Tailwind files instead of replacing them, detect frameworks, and work with aliases. Later registry work added resolve-anywhere behavior, where files can be placed outside a rigid directory and imports are resolved in multiple passes. For Button, this means local alias choices and project layout matter, but the CLI is designed to adapt instead of forcing one path structure.

Sources: apps/v4/content/docs/changelog/2024-08-npx-shadcn-init.mdx, apps/v4/content/docs/changelog/2025-04-shadcn-2-5.mdx

Core Primitives and Usage

The smallest usage shape imports Button from the generated user interface file and renders it with a variant. The docs show an outline example, which is useful because it demonstrates the component contract without requiring a larger layout. Variant names are part of the local component implementation copied into the project, so teams can add or remove variants after installation. Still, the documented catalog gives a common vocabulary across projects: default, outline, secondary, ghost, destructive, link, icon, rounded, and loading examples appear as first-party previews.

Sources: apps/v4/content/docs/components/aria/button.mdx

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

Button Group adds three named primitives in the documented import: ButtonGroup, ButtonGroupSeparator, and ButtonGroupText. The group can contain Button or Input children, optional separators, and text segments. The docs present it as a composition tree rather than a single monolithic control, which matches the shadcn/ui approach of giving developers pieces that can be rearranged. Use it for action groups, split buttons, input adornments, and compact control clusters. If a grouped control toggles selected state, the docs direct readers toward ToggleGroup instead.

Sources: apps/v4/content/docs/components/aria/button-group.mdx

import {
  ButtonGroup,
  ButtonGroupSeparator,
  ButtonGroupText,
} from "@/components/ui/button-group"
 
<ButtonGroup>
  <Button>Button 1</Button>
  <Button>Button 2</Button>
</ButtonGroup>

Variants, Sizes, and States

Size is controlled on the individual Button. That detail is important inside a Button Group because the group provides shared layout while each button still owns its own visual size. The Button page includes a dedicated size preview, and the group page repeats that sizing is applied on individual buttons. This lets a group mix components while keeping the API predictable. For example, a dense toolbar can choose compact sizes, while a marketing call-to-action can stay larger without requiring a separate container component.

Sources: apps/v4/content/docs/components/aria/button.mdx, apps/v4/content/docs/components/aria/button-group.mdx

Icons and spinners have a small but important spacing convention. The Button documentation tells you to add a data attribute marking whether an inline icon starts or ends the label. The same guidance applies to a Spinner used for a loading state. This keeps spacing consistent without guessing from child order alone. The rounded example uses a full rounding class, which shows that local utility classes remain part of the intended customization story. Button is styled, but it is not closed to normal Tailwind composition.

Sources: apps/v4/content/docs/components/aria/button.mdx

Tailwind v4 changed the default cursor for buttons from a pointer to the default cursor. The Button docs call this out directly and provide a base-layer CSS override for teams that want to preserve pointer behavior on enabled buttons and button-role elements. The same page notes that this can be enabled during project setup with the pointer flag on init. Treat cursor behavior as an application-level interaction decision rather than a variant. Apply it globally when your design system expects pointer affordance on every clickable action.

Sources: apps/v4/content/docs/components/aria/button.mdx

@layer base {
  button:not(:disabled),
  [role="button"]:not(:disabled) {
    cursor: pointer;
  }
}

Composition, Accessibility, and Layout

Button Group accessibility is explicit in the docs. The group container has a group role, keyboard navigation moves between contained buttons with the Tab key, and authors should label the group with an accessible label or a labelled-by relationship. These requirements are easy to skip when a group is treated only as visual styling, so include the label when multiple adjacent actions belong together. The group should explain its purpose, such as formatting controls, message actions, export choices, or any clustered command set.

Sources: apps/v4/content/docs/components/aria/button-group.mdx

<ButtonGroup aria-label="Button group">
  <Button>Button 1</Button>
  <Button>Button 2</Button>
</ButtonGroup>

The group examples cover more than two adjacent buttons. Orientation can switch between horizontal and vertical layouts, nested groups can create grouped spacing, and separators visually divide actions. The separator guidance is nuanced: outline buttons already have borders, so they may not need an extra divider, while other variants often benefit from one for hierarchy. The docs also show split buttons, wrapped inputs, input groups, dropdown menus, selects, and popovers. Those examples position Button Group as a layout primitive for compact command surfaces, not only as a convenience wrapper.

Sources: apps/v4/content/docs/components/aria/button-group.mdx

Right-to-left support is included on both the Button and Button Group pages through RTL previews and a pointer to the RTL configuration guide. This is also consistent with preset behavior in the apply changelog, where existing base and RTL settings are preserved when applying a new preset. If you maintain a multilingual product, verify both the standalone button and grouped layouts after changing presets or visual styles. Icons, separators, and split controls can appear visually correct in one direction while needing attention in the other.

Sources: apps/v4/content/docs/components/aria/button.mdx, apps/v4/content/docs/components/aria/button-group.mdx, apps/v4/content/docs/changelog/2026-04-shadcn-apply.mdx

API Reference

Component or helperDocumented surfaceNotes
ButtonvariantExamples include outline, default, secondary, ghost, destructive, link, icon, rounded, and spinner presentations.
ButtonsizeUsed to change the button size; Button Group sizing is controlled on each individual button.
Button child icon or spinnerdata-iconUse inline-start or inline-end so spacing is correct around icons and loading indicators.
Anchor styled as buttonbuttonVariantsUse a normal anchor with the styling helper for links instead of rendering a link through Button.
ButtonGrouporientationSupports horizontal or vertical orientation, defaulting to horizontal in the documented API table.
ButtonGroupSeparatorseparator elementRecommended for many non-outline grouped variants to improve visual hierarchy.
ButtonGroupTexttext segmentUsed as a non-button text child inside grouped layouts.

The Button API is intentionally small at the documentation level because the generated component source is meant to be owned by the application. Use the documented props and examples as the stable starting point, then inspect and edit the copied component when a project needs a new tone, size, icon convention, or loading affordance. If a project was created with newer preset flows, remember that the generated code may reflect selected libraries, icons, fonts, spacing, and visual styles. That is expected behavior, not a package mismatch.

Sources: apps/v4/content/docs/components/aria/button.mdx, apps/v4/content/docs/changelog/2025-12-shadcn-create.mdx

Next Steps

Start with the Button page when adding a single action, then read Button Group for toolbars, split controls, and mixed input compositions. If installation behaves differently than expected, review the CLI and components configuration pages because aliases, registry resolution, presets, and Tailwind setup influence where files are written and how imports are rewritten. For visual consistency, pair this page with theming, Tailwind v4, dark mode, and RTL guidance before finalizing a shared design system button. For semantics, keep the rule simple: actions use Button; navigation uses a real link styled like a button.