display
Skeleton
Eighteen placeholder treatments — sweeps, textures, opacity loops and three still ones — in any of the six tones, with a shape scale and multi-line stacks.
Examples
Eighteen treatments
One `variant` prop, eighteen surfaces. Four are opacity loops, four are highlights travelling across the box, three are lit shapes, four are textures drifting under it, and three do not move at all — for a dense table where movement is noise rather than feedback. They are composed from eight shared keyframes; the gradient underneath is what separates the shimmer from the sheen. Every tile copies on its own.
Opacity loops
Travelling highlights
Lit shapes
Drifting textures
Still
Colour
The placeholder is not hardcoded grey. `tone` takes the same six semantic tones as every other component, and both the fill and the travelling highlight come from that tone — so a skeleton standing in for a danger panel reads as one. Underneath they are two variables, `--sk-subtle` and `--sk-subtle-hover`, which you can point anywhere: the last group sets plain hex values and never touches the token system.
Semantic tones
Plain hex values
Sizes
Five rungs, and `shape` decides what they measure: the diameter of a disc, the height of a line, the height and width of a pill, the depth of a block. That is why the scale is one prop rather than a height passed per shape — a `size="lg"` avatar and a `size="lg"` heading line up with each other whatever they stand in for. `className` still overrides any of it.
Circle
Text
Pill
Rounded
Shapes and lines
`shape` is the outline of the thing being waited for. `lines` stacks text rows with the last one short, staggering each row a beat behind the one above so a sweep crosses the paragraph rather than every row at once.
Shapes
Lines
Card skeletons
Three cards composed from the same component: a media card with a thumbnail, title and byline; a profile card with an avatar and a paragraph; and a row of stat tiles. Nothing here is a Skeleton feature — a card placeholder is a card built out of placeholders, which is the point. Keep one treatment per card: two sweeps at different tempos inside one border read as two separate things loading. Each card copies on its own.
Lists and tables
Match the real layout rather than an approximation of it — a placeholder that shifts on load is worse than no placeholder. The table on the right uses `flat`, because forty rows shimmering at once is the strongest argument there is for a still treatment.
Own the source
Noksha ships as a package and as copy-paste source. Take the files and they are yours to change. These are read from the generated registry, so they are exactly what the library ships — never a paraphrase of it.
Take these files, and internal helpers along with them — the imports below point at them. Or let the CLI do it: npx @noksha-ui/cli add skeleton writes them, follows the same dependency graph, and fixes up the imports.
export { Skeleton, skeletonStackVariants, skeletonVariants } from './skeleton.js';
export type {
SkeletonProps,
SkeletonShape,
SkeletonSize,
SkeletonSpeed,
SkeletonTone,
SkeletonVariant,
} from './skeleton.types.js';API reference
Accepted values
- SkeletonVariant
pulsebreatheblinkfadeshimmerwavesheensliderippleglowbargradientstripegriddotsoutlinedashedflat- SkeletonShape
textrectroundedcirclepill- SkeletonSize
xssmmdlgxl- SkeletonSpeed
slownormalfast
SkeletonProps
Also accepts everything from Omit<React.HTMLAttributes<HTMLSpanElement>, 'children'>.
| Prop | Type | Description |
|---|---|---|
| variant | SkeletonVariant | Surface treatment. Independent of shape, tone and speed. |
| shape | SkeletonShape | Outline of the placeholder, and what `size` measures. |
| size | SkeletonSize | Rung of the size scale. A line of text, a disc, a block — one scale. |
| tone | SkeletonTone | Semantic colour. `neutral` is the usual grey placeholder. |
| speed | SkeletonSpeed | Scales the treatment's own tempo rather than replacing it. |
| lines | number | Stacks this many rows, staggered, with the last one short. |
| label | string | null | Accessible name. Placeholders are silent by default. |