Skeleton
A React component in Beamline's Feedback category.
Holds the shape of content while it loads, then crossfades into it, so nothing jumps.
Use it for
- Reserving layout while content loads so nothing jumps.
Not for
- Long operations with progress (progress). Empty results (empty-state).
Anatomy
- root (aria-busy region)
- avatar circle (optional)
- text lines (last one shorter)
- content (children, revealed when loaded)
- group (SkeletonGroup: many shapes under one visibility and motion check)
- line (SkeletonLine: one line of text that has not arrived, exactly the surrounding text style's line tall)
Variants
- shape: lines, avatar + lines, custom (SkeletonBlock pieces), many shapes (SkeletonGroup with `sheen` elements inside)
States
- loading
- loaded (crossfade into children)
Keyboard
- None; the region is aria-busy while loading and announces its label.
Motion
A soft sheen crosses the blocks while loading; it stops entirely under reduced motion. Loaded content fades in over --pui-duration-standard.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
loading | boolean | true | With children: shows the placeholder while true, the children after. |
lines | number | 3 | |
avatar | boolean | — | |
label | string | "Loading content" | Announced to assistive tech. |
children | ReactNode | — | The real content. |
classNames | SkeletonClassNames | — | |
style / ref | CSSProperties / native Ref | — | Root styles; ref targets native wrapper div; SkeletonBlock span. |
Built from
- SkeletonBlock: one placeholder shape (any width, height, radius) for building the real layout's silhouette.
- SkeletonGroup: many placeholder shapes (heatmap cells, chart bars, a list's loading rows) under one visibility and motion check; every element with the `sheen` class inside it, at any depth, pauses off screen and stills under reduced motion together. Use it instead of hundreds of SkeletonBlocks, and to keep a loading list's real row structure.
- SkeletonLine: inside a SkeletonGroup, a placeholder for one line of text; give it the real text's classes and a width, and the loaded line replaces it without a shift.
Dependencies
motion
Import
import { SkeletonBlock, SkeletonGroup, SkeletonLine, Skeleton } from "@/components/skeleton/skeleton";
Get it
Skeleton is part of Beamline: 190 React components and screens your coding agent (Claude Code, Codex, Cursor or any MCP client) installs into your app through Beamline's MCP server, as a ready-built package or as plain React source you can change. $49 one payment (regular $200), no subscription, a year of updates, one licence for your whole team. Get Beamline · Connect your agent
More in Feedback
- Alert: A message that stays until it is dealt with: what happened, what to do, an action; danger and warning are announced; dismissing folds its height away.
- Announcement bar: A banner across the top for news and offers: messages take turns, a countdown ticks, and dismissing folds it away and can remember it.
- Empty state: What a place will hold and the first step to fill it, instead of a blank; a compact size for panels and filtered tables.
- Notification centre: Updates that wait to be read: a bell with the unread count opens All / Unread, new and earlier groups, and per item mark read or dismiss.
- Progress: How much of a known task is done, or a moving bar when the length is unknown, with an optional label and value.
- Spinner: A ring that spins while work runs and closes into a drawn check or cross when it ends.
- Usage meter: An allowance and what fills it: one bar split by source, the room left, a warning near the limit and the overflow in its own red well past a notch at the…