Skip to content

Now in the official shadcn registry directory.

Start free

Skeleton

A pulsing loading placeholder on the surface tokens - compose several to mirror the shape of the content that is loading.

displayfeedback
A free styled version is available

Installation

Run the following command

npx shadcn@latest add @ai2/skeleton

The @ai2/tokens theme and the component file are installed together.

Usage

TS
import { Skeleton } from "@/components/ui/skeleton"

<Skeleton shape="line" className="w-48" />

Skeleton renders a pulsing <div> - width, height and shape come entirely from className.

Examples

Shapes

The shape prop sets the base geometry: line for text bars, circle for avatars and rect (the default) for media blocks. className refines the exact width, height and radius.

Animation

animation="pulse" (the default) uses Tailwind's animate-pulse; animation="none" renders a static block. There is deliberately no shimmer option: a shimmer needs a CSS keyframe, and a registry theme item cannot ship one, so add it in your own globals if you need it.

Card skeleton

Compose multiple Skeletons to mirror the layout of the loading content - matching shapes keep the swap from placeholder to content calm.

Props

Skeleton adds two axes on top of every native <div> prop; className still fine-tunes the exact size and radius.

PropTypeDefaultDescription
shape"line" | "circle" | "rect""rect"Base geometry. line is h-4 w-full, circle is a rounded-full square, rect is a plain rounded block. className fine-tunes size on top.
animation"pulse" | "none""pulse"pulse uses Tailwind's animate-pulse; none renders a static block. There is deliberately no shimmer option.

ai2 Skeleton: loading placeholders for React, shaped by className

The ai2 Skeleton is a shadcn-compatible skeleton component for React, styled with Tailwind CSS v4. It renders a pulsing placeholder block that stands in for content while it loads: text lines, avatars, cards, table rows, whole page sections. The pulse and the fill color both come from the shared ai2 tokens, so placeholders match your theme in light and dark mode.

It ships through the shadcn registry format, so one CLI command, an MCP agent, or a copy-paste puts the source in your own project. You own the file; there is no runtime dependency on ai2 itself. The live example above is the exact component you get.

What is the ai2 Skeleton?

It is a single part: Skeleton, a plain <div> on the bg-surface-3 token. There is no radix primitive; a shape prop (line, circle, rect) and an animation prop (pulse, none) set the geometry and the pulse, and className fine-tunes width, height and radius on top. The anatomy stays shadcn/ui compatible, so existing snippets and AI agents keep working.

Because it is just a styled div, you compose loading states the same way you compose layouts: a circle for the avatar, bars for the text lines, a large rounded block for the media. Matching the real content's shape is what makes the swap from placeholder to data feel calm instead of jarring.

Why use it

  • Perceived performance: A skeleton that mirrors the incoming layout tells users what is coming and where, which reads faster than a spinner or a blank region.
  • Two simple axes: A shape prop (line, circle, rect) and an animation prop (pulse, none) cover the common cases, and Tailwind className handles every exact size on top.
  • Layout stability: Sizing the skeleton like the real content reserves the space up front, so the page does not shift when data arrives.
  • Theme-correct by default: The fill is the surface-3 token from the shared theme file, not a hardcoded gray, so placeholders look right in both light and dark mode.
  • Agent-readable metadata: The registry item describes the component and its intended use in plain words, so an MCP agent can find, inspect and install it without guessing.

Features

  • shadcn registry install: One command adds the component and the @ai2/tokens theme to your project. There are no npm dependencies beyond the cn util.
  • Pulse or none: The animation prop is pulse (Tailwind's animate-pulse, pure CSS) or none for a static block. There is deliberately no shimmer, since a keyframe cannot travel through a registry theme item.
  • Shape prop plus className: The shape prop gives you line, circle and rect out of the box, and className refines the exact width, height and radius on top.
  • Composable into full layouts: Stack several Skeletons in flex or grid wrappers to mirror an entire card, list row or page section while it loads.
  • Data attribute for styling: The element exposes data-slot="skeleton", so you can target every placeholder from CSS without forking the component.
  • TypeScript source: The file you install is typed and forwards every native div prop, including aria attributes and event handlers.

Production tips

  • Mirror the real layout: Copy the dimensions of the loaded state: same heights, widths and gaps. A skeleton that does not match the final layout causes a visible jump when content lands.
  • Hide skeletons from screen readers: The component ships no ARIA attributes of its own. Put aria-hidden="true" on the skeleton region and aria-busy="true" on the loading container, and announce the loaded state instead.
  • Vary the bar widths: Real text lines end at different points. Use w-3/4 and w-1/2 style widths on consecutive bars so the placeholder reads as text, not as stripes.
  • Do not skeleton everything: Reserve skeletons for content with a known shape. For indeterminate operations like a form submit, a spinner or a progress bar communicates better.
  • Keep it brief: Skeletons are for sub-second to few-second waits. If loading routinely takes longer, show real progress or partial data instead of an endless pulse.

Works with the rest of ai2

The skeleton composes naturally with the rest of the registry. Mirror an ai2 Avatar with a rounded-full circle, sketch an ai2 Card while its data loads, or fill ai2 Table rows with bars during a fetch.

For loading states without a fixed shape, pair it with the ai2 Spinner for indeterminate waits or ai2 Progress when you can report completion. Everything shares one token source, so loading and loaded states stay visually consistent in both modes.

FAQs

Get new components in your inbox

Component drops, new themes and release notes. No spam, and you can unsubscribe from any email.

© 2026 ai2 design system · MIT licensed · Built with its own components