What is Badge?
Badge: A badge is a small, non-interactive label attached to another element that shows a status, a category or a count, such as Paid, Beta or 3 unread.
A badge is a short label in a small pill or rounded rectangle: Paid, Draft, Beta, Admin, New, or a number on an icon that counts unread messages. It annotates something else, a row, a card, a tab, a menu item, and it reads in a glance because it is short and consistently colored. Badges are among the smallest components in a kit and among the most used, which is why their variants, sizes and colors need to be decided once and reused everywhere.
Kinds of badge
- Status badges show the state of a record: Paid, Overdue, Running, Failed. They map to the semantic colors of the design system, such as success, warning and danger.
- Category or tag badges are neutral labels that classify: Design, Backend, Q3.
- Count badges sit on an icon or a tab and show a number, usually capped at 99+.
- Dot badges are a count badge with no number, only a colored dot meaning "something is here".
- Environment and version badges label a build: Production, Staging, v2.4.
Accessibility
A badge is text, so most of the work is making sure the text makes sense out of context. A count badge on a bell icon needs the icon button's name to include it, "Notifications, 3 unread", through aria-label or visually hidden text, because a bare "3" means nothing. Color must never be the only signal: a status badge says Overdue in words, and a dot badge next to a name gets a hidden label such as "Online".
Badge text is small, often 11 or 12px, and small text needs the full 4.5:1 WCAG contrast against the badge background, not the 3:1 allowed for large text. Tinted backgrounds like 10 percent of the accent over a white surface make this harder than it looks; check the text color against the mixed result. A badge is not a button. If it must be clickable, render it as a link or button and give it a visible focus ring.
How to build one in React
MiniDev's Badge is a small pill with seven variants. Its render prop swaps the element, so a badge can be a link without losing its styling:
import Link from "next/link"
import { Badge } from "@/components/ui/badge"
export function InvoiceRow({ status, tag }: { status: "paid" | "overdue"; tag: string }) {
return (
<div className="flex items-center gap-2">
<Badge variant={status === "paid" ? "accent" : "destructive"}>{status === "paid" ? "Paid" : "Overdue"}</Badge>
<Badge variant="outline" render={<Link href={"/tags/" + tag} />}>{tag}</Badge>
</div>
)
}
Keep badge text to one or two words, use sentence case, and never put a badge inside a button label. For states with an icon and tone built in, use StatusBadge; EnvBadge, VersionBadge and LatencyBadge cover developer tooling. See the feedback category for the rest.
BadgeuiShadcn style badge in seven variants: default, accent, secondary, destructive, outline, ghost and link. Renders as a span or any element, with icon support.npx shadcn@latest add @minidev/badgeStatus BadgeuiTailwind status badge with a tinted fill, hairline border and colored dot in neutral, success, warning, danger, accent and info tones that read as one set.npx shadcn@latest add @minidev/status-badge