---
title: "Button"
description: "Displays a Discord-styled button with brand, secondary, success, danger and link variants."
---

The button carries six intents and four sizes. Which one you reach for is a statement about what the action does, not about how it should look — `danger` is destructive, `success` is confirming, `link` is navigation that happens to sit in a row of buttons.

_Live example of Button — see the page for the rendered demo._

## Installation

```bash
npx newtui@latest add button
```

npm dependencies: class-variance-authority.

Files written — React: components/ui/button.tsx. Vue: components/ui/button/Button.vue, components/ui/button/index.ts.

## Usage

React:

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

Vue:

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

## API reference

**`Button`**

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `variant` | `"primary" \| "secondary" \| "success" \| "danger" \| "link"` | `"primary"` | What the action does. Never picked for its colour. |
| `size` | `"default" \| "sm" \| "lg" \| "icon"` | `"default"` | Padding and text size. `icon` makes it a circle. |
| `emoji` | `string` | — | Image URL rendered before the label. |
| `emojiAlt` | `string` | `""` | Accessible name for the emoji. Empty hides it from readers, which is right when the label already says it. |
| `launchIcon` | `boolean` | `variant === "link"` | Link-out glyph after the label. |

Every part also accepts the native attributes of the element it renders, and a `className` that is merged rather than replaced.

## Accessibility

It renders a real `<button>`, so `Enter` and `Space` activate it and `disabled` is honoured by the browser rather than emulated. An icon-only button (`size="icon"` with no text) has no visible text: give it an `aria-label`. The focus ring is a 2px `--newt-text-link` outline at 2px offset, and it is not removed on `:focus-visible`.

## Tokens

Button reads its colours, radii and motion from the `--newt-*` tokens. Override a token rather than editing the component.
