Philosophy
Users feel the care.
Every loading state is a moment of trust. What fills that gap tells users whether you thought about them.
Loading text
No shape, no context. The user is left in the dark.
Spinner
At least it moves. But what exactly is coming next?
Generic bars
Most libraries stop here. Drifts when your UI evolves.
skelter
The loading experience your users deserve.
The best products treat every state as intentional.
Not just the happy path. Not just the hero screen. The loading moment is your UI's first visible frame: make it accurate.
Live demo
See it in action
Real components: skelter measures their layout and generates bones automatically.
Get started in minutes
A full demo app · 8 cards, 7 animations, real-time open source data. Zero skeletons written by hand. Each card exposes its source in a built-in VS Code mini-editor.
Try it on your phone
The React Native demo is live. Scan the QR code with Expo Go to see the skeletons running natively on your device.
Scan avec Expo Go
The difference
// Other libs: you write the component...function ArticleCard({ article }) {return (<View><Image source={{ uri: article.cover }}style={{ height: 160 }} /><Text style={{ fontSize: 'var(--fs-lg)' }}>{article.title}</Text><Text style={{ color: '#888' }}>{article.excerpt}</Text></View>);}// ...then write it AGAIN as a skeleton.const ArticleCardSkeleton = () => (<SkeletonPlaceholder><View style={{ height: 160 }} /><View style={{ width: '80%', height: 18 }} /><View style={{ width: '60%', height: 14 }} /></SkeletonPlaceholder>);// Two components. Always drifting out of sync.
// skelter (React Native): write it once.import { withSkeleton } from 'react-zero-skeleton';function ArticleCard({ article }) {return (<View><Image source={{ uri: article.cover }}style={{ height: 160 }} /><Text style={{ fontSize: 'var(--fs-lg)' }}>{article.title}</Text><Text style={{ color: '#888' }}>{article.excerpt}</Text></View>);}export default withSkeleton(ArticleCard);// Use it:<ArticleCard hasSkeleton isLoading={isLoading}article={data} />// skelter measures the layout.// Bones generated automatically. Always in sync.
Same import react-zero-skeleton: bundler picks the right version automatically.