Free shadcn/ui alert component for React — an inline message banner with an icon, title, and description. Default and destructive variants plus success/warning/info, actions, dismissible, and a full-width banner.

Installation

1 Configure registry — once per project
{
  "registries": {
    "@designrevision": "https://registry.designrevision.com/r/{name}.json"
  }
}

Add to your existing components.json. Requires shadcn/ui v2.3+.

2 Install the component

Packages

utils

Props

variant = "default"
"default" | "destructive"

Visual style. default for neutral messages, destructive for errors.

An inline alert (a message banner) — distinct from Alert Dialog (the modal). Compose <Alert> with <AlertTitle> and <AlertDescription>; drop a Lucide icon as the first child and the CSS grid lays it out automatically. variant is "default" or "destructive" (extend the cva for success/warning/info). It carries role="alert" so screen readers announce it.

Copied!
components/ui/alert.tsx
import * as React from "react"
import { cva, type VariantProps } from "class-variance-authority"

import { cn } from "@/lib/utils"

const alertVariants = cva(
  "relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current",
  {
    variants: {
      variant: {
        default: "bg-card text-card-foreground",
        destructive:
          "text-destructive bg-card [&>svg]:text-current *:data-[slot=alert-description]:text-destructive/90",
      },
    },
    defaultVariants: {
      variant: "default",
    },
  }
)

function Alert({
  className,
  variant,
  ...props
}: React.ComponentProps<"div"> & VariantProps<typeof alertVariants>) {
  return (
    <div
      data-slot="alert"
      role="alert"
      className={cn(alertVariants({ variant }), className)}
      {...props}
    />
  )
}

function AlertTitle({ className, ...props }: React.ComponentProps<"div">) {
  return (
    <div
      data-slot="alert-title"
      className={cn(
        "col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight",
        className
      )}
      {...props}
    />
  )
}

function AlertDescription({
  className,
  ...props
}: React.ComponentProps<"div">) {
  return (
    <div
      data-slot="alert-description"
      className={cn(
        "text-muted-foreground col-start-2 grid justify-items-start gap-1 text-sm [&_p]:leading-relaxed",
        className
      )}
      {...props}
    />
  )
}

export { Alert, AlertTitle, AlertDescription }

Examples

Default & destructive

The canonical alert — icon, title, and description in the two built-in variants.

Packages

lucide-react
alert

Props

No props documented yet.

Copied!
components/ui/alert-demo-01.tsx
import { CircleAlertIcon, TerminalIcon } from "lucide-react"

import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"

export default function AlertDemo01() {
  return (
    <div className="w-full max-w-md space-y-4">
      <Alert>
        <TerminalIcon />
        <AlertTitle>Heads up!</AlertTitle>
        <AlertDescription>
          You can add components to your app using the CLI.
        </AlertDescription>
      </Alert>
      <Alert variant="destructive">
        <CircleAlertIcon />
        <AlertTitle>Error</AlertTitle>
        <AlertDescription>
          Your session has expired. Please log in again.
        </AlertDescription>
      </Alert>
    </div>
  )
}

Success / warning / info

Extra status colors built by overriding the border, text, and icon color.

Packages

lucide-react
alert

Props

No props documented yet.

Copied!
components/ui/alert-variants-01.tsx
import { CircleCheckIcon, InfoIcon, TriangleAlertIcon } from "lucide-react"

import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"

export default function AlertVariants01() {
  return (
    <div className="w-full max-w-md space-y-4">
      <Alert className="border-green-500/50 text-green-700 dark:text-green-400 [&>svg]:text-green-600">
        <CircleCheckIcon />
        <AlertTitle>Success</AlertTitle>
        <AlertDescription className="text-green-700/80 dark:text-green-400/80">
          Your changes have been saved.
        </AlertDescription>
      </Alert>
      <Alert className="border-amber-500/50 text-amber-700 dark:text-amber-400 [&>svg]:text-amber-600">
        <TriangleAlertIcon />
        <AlertTitle>Warning</AlertTitle>
        <AlertDescription className="text-amber-700/80 dark:text-amber-400/80">
          Your trial ends in 3 days.
        </AlertDescription>
      </Alert>
      <Alert className="border-blue-500/50 text-blue-700 dark:text-blue-400 [&>svg]:text-blue-600">
        <InfoIcon />
        <AlertTitle>Information</AlertTitle>
        <AlertDescription className="text-blue-700/80 dark:text-blue-400/80">
          A new version is available.
        </AlertDescription>
      </Alert>
    </div>
  )
}

Title-only & description-only

Minimal alerts — the icon column collapses automatically when there's no icon.

Packages

lucide-react
alert

Props

No props documented yet.

Copied!
components/ui/alert-simple-01.tsx
import { CheckIcon } from "lucide-react"

import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"

export default function AlertSimple01() {
  return (
    <div className="w-full max-w-md space-y-4">
      {/* Title only, with an icon */}
      <Alert>
        <CheckIcon />
        <AlertTitle>Your changes have been saved.</AlertTitle>
      </Alert>
      {/* Description only, no icon — the grid collapses the icon column */}
      <Alert>
        <AlertDescription>
          We use cookies to improve your experience.
        </AlertDescription>
      </Alert>
    </div>
  )
}

With actions

Trailing action buttons aligned under the content — the update/notice pattern.

Packages

lucide-react
alert
button

Props

No props documented yet.

Copied!
components/ui/alert-action-01.tsx
import { RocketIcon } from "lucide-react"

import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"
import { Button } from "@/components/ui/button"

export default function AlertAction01() {
  return (
    <Alert className="w-full max-w-md">
      <RocketIcon />
      <AlertTitle>Update available</AlertTitle>
      <AlertDescription>
        A new version is ready to install.
      </AlertDescription>
      <div className="col-start-2 mt-2 flex gap-2">
        <Button size="sm">Update now</Button>
        <Button size="sm" variant="ghost">
          Later
        </Button>
      </div>
    </Alert>
  )
}

Dismissible

A closable alert — an X button toggles it with `useState`.

Packages

lucide-react
alert
button

Props

No props documented yet.

Copied!
components/ui/alert-dismissible-01.tsx
"use client"

import * as React from "react"
import { InfoIcon, XIcon } from "lucide-react"

import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"
import { Button } from "@/components/ui/button"

export default function AlertDismissible01() {
  const [open, setOpen] = React.useState(true)

  if (!open) {
    return (
      <Button variant="outline" size="sm" onClick={() => setOpen(true)}>
        Show alert
      </Button>
    )
  }

  return (
    <Alert className="relative w-full max-w-md pr-12">
      <InfoIcon />
      <AlertTitle>New feature</AlertTitle>
      <AlertDescription>
        Dark mode is now available in settings.
      </AlertDescription>
      <Button
        variant="ghost"
        size="icon"
        className="absolute top-2 right-2 size-7"
        onClick={() => setOpen(false)}
      >
        <XIcon />
        <span className="sr-only">Dismiss</span>
      </Button>
    </Alert>
  )
}

Announcement banner

A full-width, high-emphasis banner — a colored Alert with an inline link.

Packages

lucide-react
alert

Props

No props documented yet.

Copied!
components/ui/alert-banner-01.tsx
import { MegaphoneIcon } from "lucide-react"

import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"

export default function AlertBanner01() {
  return (
    <Alert className="bg-primary text-primary-foreground border-primary w-full [&>svg]:text-current">
      <MegaphoneIcon />
      <AlertTitle>Black Friday — 50% off all plans</AlertTitle>
      <AlertDescription className="text-primary-foreground/90">
        Offer ends Monday.{" "}
        <a href="#" className="font-medium underline underline-offset-2">
          Claim it now
        </a>
        .
      </AlertDescription>
    </Alert>
  )
}

With a list

A destructive alert whose description holds a bulleted list — a form-error summary.

Packages

lucide-react
alert

Props

No props documented yet.

Copied!
components/ui/alert-list-01.tsx
import { CircleAlertIcon } from "lucide-react"

import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"

export default function AlertList01() {
  return (
    <Alert variant="destructive" className="w-full max-w-md">
      <CircleAlertIcon />
      <AlertTitle>Unable to submit your form</AlertTitle>
      <AlertDescription>
        <ul className="list-inside list-disc text-sm">
          <li>Email is required</li>
          <li>Password must be at least 8 characters</li>
          <li>You must accept the terms</li>
        </ul>
      </AlertDescription>
    </Alert>
  )
}

Frequently asked questions

It is an inline message banner — a bordered box with an optional icon, a title (AlertTitle), and a description (AlertDescription) — used to surface a status or notice in the page flow. It is a static element (no dependency), with default and destructive variants out of the box and a CSS grid that lays out the icon automatically.
They are different components. Alert is an inline message that sits in the page (a banner or notice). Alert Dialog is a modal that interrupts the user and asks them to confirm or cancel a destructive action. If you want a message in the layout, use Alert; if you need a blocking confirm, use Alert Dialog.
Two built in: default (neutral) and destructive (errors). For success, warning, and info, override the border, text, and icon color with a className — the Success / warning / info example shows green, amber, and blue alerts. You can also bake those into the cva variants if you use them a lot.
Drop a Lucide icon as the first child of : the component uses a CSS grid that detects an svg (has-[>svg]) and creates an icon column automatically, so the title and description align beside it. With no icon, that column collapses and the content spans the full width.
Track an open state and render a close button: a ghost icon Button positioned in the corner that sets the state to false. The Dismissible example does this with useState. For transient, stacking notifications instead, use a toast (Sonner).
Use the Alert with a colored background and a link — the Announcement banner example sets bg-primary text-primary-foreground for a high-emphasis bar with an inline call to action. Drop it at the top of a page or section.
The Alert has role="alert", so screen readers announce its content when it appears — appropriate for important, time-sensitive messages. For non-urgent notices you can lower the urgency (e.g. role="status"). Decorative icons are hidden from the accessible name; the title and description carry the meaning.