Skeleton
An animated pulse placeholder for loading states
Skeletons stand in for content while it's still loading. They preserve the layout of the real UI so the page doesn't jump when data arrives, and the soft pulse animation signals that something is happening without demanding attention. Use skeletons in place of spinners when you can predict the rough shape of the incoming content — a card, a row, an avatar — because matching the final layout reduces perceived wait time more than a generic loader.
When to use
- The shape of the data is known ahead of time (lists, cards, profile headers, table rows).
- The wait is long enough to be noticed (roughly 300ms or more) but short enough that a full-page state would be overkill.
- You want to avoid layout shift when content swaps in.
Prefer a spinner or progress indicator when the loading duration is unpredictable, when the layout cannot be approximated, or when the user has just triggered an explicit action like a form submission.
Installation
bunx @prototyperco/cli add skeletonpnpm dlx shadcn@latest add https://prototyper-ui.com/r/skeleton.jsonnpx shadcn@latest add https://prototyper-ui.com/r/skeleton.jsonyarn dlx shadcn@latest add https://prototyper-ui.com/r/skeleton.jsonbunx --bun shadcn@latest add https://prototyper-ui.com/r/skeleton.jsonThis will add the following files to your project:
components/ui/skeleton.tsx
Usage
import { Skeleton } from "@/components/ui/skeleton";
<Skeleton className="h-4 w-[200px]" />;Examples
Card
Styling
Data Slots
Use data-slot attributes to target the skeleton in CSS:
| Slot name | Element |
|---|---|
skeleton | The <div> root |
Customization Examples
/* Change animation to a shimmer */
[data-slot="skeleton"] {
@apply animate-shimmer;
}{
/* Size and shape via className */
}
<Skeleton className="size-12 rounded-full" />;API Reference
Skeleton
An animated loading placeholder.
Prop
Type
Extends React.ComponentProps<"div">. All standard div props are forwarded via ...props.
Accessibility
Keyboard Interactions
Skeleton is a non-interactive presentational element and does not have keyboard interactions.
ARIA Attributes
- Skeleton renders as a plain
<div>with no implicit ARIA role. - For screen readers, set
aria-busy="true"on the parent container while loading and remove it when content arrives. - If the skeleton represents content that will be announced (such as a status message), pair it with
aria-live="polite"on the same container so assistive tech picks up the final value once it swaps in. - Respect
prefers-reduced-motion: the default pulse animation is subtle, but you can disable it entirely by overriding the animation utility for users who opt out.