- Accordion
- Alert
- Alert Dialog
- Aspect Ratio
- Avatar
- Badge
- Breadcrumb
- Button
- Button Group
- Calendar
- Card
- Carousel
- Chart
- Checkbox
- Collapsible
- Combobox
- Command
- Context Menu
- Data Table
- Date Picker
- Dialog
- Drawer
- Dropdown Menu
- Empty
- Field
- Hover Card
- Input
- Input Group
- Input OTP
- Item
- Kbd
- Label
- Menubar
- Native Select
- Navigation Menu
- Pagination
- Popover
- Progress
- Radio Group
- Resizable
- Scroll Area
- Select
- Separator
- Sheet
- Sidebar
- Skeleton
- Slider
- Sonner
- Spinner
- Switch
- Table
- Tabs
- Textarea
- Toast
- Toggle
- Toggle Group
- Tooltip
- Typography
import { RiCheckLine, RiSparklingFill } from "@create-ui/assets/icons"
import { Badge } from "@/components/ui/badge"Description
Badge is a small, non-interactive label used to tag content with a status, count, or category. It is a single-element component rendered as a <span> by default, with optional leading and trailing icons.
Reach for it when you need to surface a piece of metadata next to other content — an item state next to a row, a count on a navigation item, a tag in a list, a category on a card. The visual weight is intentionally low so it complements the content it sits beside instead of competing with it.
Don't use Badge when the user needs to interact with it. If it triggers an action, use Button. If it represents an inline call-to-attention with title and body copy, use Alert. If it's a colored dot indicating presence (online / offline / away), use Status Badge. Reserve Badge for passive labels.
Installation
pnpm dlx createui@latest add badge
Usage
import { Badge } from "@/components/ui/badge"<Badge>New</Badge>Examples
Variants
variant sets the semantic color. Eleven options cover product intents (primary), neutral metadata, status tones (success, error, warning, info), and specialty tones (verified, highlighted, away, inverse, disabled).
import { Badge } from "@/components/ui/badge"
export function BadgeVariants() {Appearance
appearance controls fill weight. soft is the default and works well in dense lists. solid is high-contrast for emphasis, outline is quiet, and ghost strips the background entirely.
import { Badge } from "@/components/ui/badge"
export function BadgeAppearance() {Sizes
Three sizes — xs, sm, md — match the surrounding type scale. sm is the default.
import { Badge } from "@/components/ui/badge"
export function BadgeSizes() {Shape
shape="pill" makes the badge fully rounded; rounded (default) follows the size's radius scale.
import { Badge } from "@/components/ui/badge"
export function BadgeShape() {With Icon
Use leadingIcon and trailingIcon to render an icon inline. The component handles spacing and sizing per the active size.
import { RiArrowRightLine, RiSparklingFill } from "@create-ui/assets/icons"
import { Badge } from "@/components/ui/badge"Icon Only
iconOnly removes horizontal padding and forces a square footprint. Always pair with an aria-label so screen readers can announce the meaning.
import { RiSparklingFill } from "@create-ui/assets/icons"
import { Badge } from "@/components/ui/badge"Number Only
numberOnly is the count style — square-ish, centered, designed for notification numerals (1, 12, 99+) on navigation items or avatars.
import { Badge } from "@/components/ui/badge"
export function BadgeNumberOnly() {Accessibility
Badge is a passive label. By default it renders as a <span> and is not focusable; there are no keyboard interactions to document. If you render it as a link or button via the asChild prop, focus and keyboard behavior come from that underlying element.
| Key | Description |
|---|---|
| — | Not focusable by default. |
ARIA notes:
- The component sets no implicit role; treat purely-decorative badges as such (e.g. add
aria-hidden="true"). - For badges that carry meaning beyond their visible label (e.g. an unread count), make sure the surrounding context exposes that meaning — either through the badge's text content or with
aria-labelon the parent control. - When using
iconOnly, always provide anaria-labelbecause the visual icon alone is not announced.
Styling
Tailwind override — pass className to merge Tailwind classes with the component's CVA classes (via cn()):
<Badge className="tracking-wide uppercase">Beta</Badge>Data slots and attributes — the component sets these for CSS targeting:
data-slot="badge"on the root element.data-slot="badge-icon"on each icon wrapper (leading and trailing).data-slot="badge-label"on the inner text wrapper.data-variant="<variant>",data-appearance="<appearance>",data-size="<size>"on the root.
Target a specific state in CSS:
[data-slot="badge"][data-variant="error"] {
/* … */
}Design Tokens
The component reads from the unified semantic token set. Color tokens are picked per variant × appearance:
- Solid backgrounds:
--color-primary-base,--color-strongest,--color-error-base,--color-success-base,--color-warning-weak,--color-info-base,--color-verified-base,--color-highlighted-base,--color-away-base,--color-static. - Soft backgrounds: matching
*-weakest(or--color-weakforneutral,--color-heavyforinverse). - Outline borders: matching
*-base(or--color-strongforneutral,--color-weakestforinverse,--color-mediumfordisabled). - Text: matching
*-basefor non-solid,--color-staticfor solid,--color-strongestforinversesolid,--color-disabledfordisabled. - Radius:
rounded-sm(xs),rounded-md(sm),rounded-lg(md),rounded-full(pill).
Token definitions live in apps/v4/styles/globals.css.
Related Components
- Status Badge — colored dot + label for presence states (online, offline, away).
- App Store Badge — branded download CTA for App Store / Play Store.
- Button — use this when the element needs to be interactive.
- Alert — use this for full callouts with title and description, not inline labels.
API Reference
Badge
Passive label for tagging content with a status, count, or category. Extends React.ComponentProps<"span">, so any standard span attribute (id, role, aria-*, onClick, etc.) is accepted.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
asChild | boolean | false | Render as the child element via Radix Slot. Use to make the badge act as a link. |
leadingIcon | React.ReactNode | — | Icon rendered before the label. Ignored when iconOnly or numberOnly is true. |
trailingIcon | React.ReactNode | — | Icon rendered after the label. Ignored when iconOnly or numberOnly is true. |
iconOnly | boolean | false | Square footprint with no horizontal padding; renders children as the only content. |
numberOnly | boolean | false | Count-style footprint (centered, min-width per size) for short numerals. |
className | string | — | Tailwind classes merged with the component's CVA classes via cn(). |
children | React.ReactNode | — | Badge content. Text for default mode, an icon for iconOnly, a numeral for numberOnly. |
Variants
| Variant | Options | Default | Description |
|---|---|---|---|
variant | "primary" "neutral" "error" "success" "warning" "info" "verified" "highlighted" "away" "inverse" "disabled" | "primary" | Semantic color intent. |
appearance | "solid" "outline" "soft" "ghost" | "soft" | Fill weight. solid for emphasis, ghost for no surface. |
size | "xs" "sm" "md" | "sm" | Size scale; controls height, padding, type, and icon size. |
shape | "rounded" "pill" | "rounded" | pill is fully rounded; rounded follows the size scale. |