Side-by-side
Same UserCard. Same loading flag. Same visual output. One is hand-authored placeholders (22 lines), the other is a wrapper (6 lines).
react-loading-skeleton
22 lines · maintains parallel skeleton tree
@kenildev007/skeleto
6 lines · auto-generated from real DOM
Loading content
// react-loading-skeleton — manual parallel tree (~22 lines)
import Skeleton from 'react-loading-skeleton';
import 'react-loading-skeleton/dist/skeleton.css';
function UserCard({ user, loading }) {
if (loading) {
return (
<div className="card">
<Skeleton circle width={64} height={64} />
<div className="body">
<Skeleton width={140} height={20} />
<Skeleton width={280} height={14} count={2} />
<div className="row">
<Skeleton width={56} height={24} borderRadius={12} />
<Skeleton width={72} height={24} borderRadius={12} />
</div>
</div>
</div>
);
}
return <RealUserCard user={user} />;
}// Skeleto — wrap and forget (3 lines)
import { AutoSkeleton } from '@kenildev007/skeleto';
function UserCard({ user, loading }) {
return (
<AutoSkeleton loading={loading}>
<RealUserCard user={user} />
</AutoSkeleton>
);
}Lines of code
RLS
22SA
6Web
RLS
✓SA
✓React Native
RLS
✗SA
✓Expo Go
RLS
✗SA
✓Auto-measure
RLS
✗SA
✓Drift-proof
RLS
✗SA
✓SSR no-flash
RLS
manualSA
built-inBundle (gzip)
RLS
3.0 KBSA
5.3 KB (web+core)What you save
- 16 lines per component — that's 73% less skeleton code per file
- Zero drift — when the real component changes its layout, the skeleton updates automatically. With the manual approach you forget to update the skeleton tree and it goes stale.
- One API for web + RN + Expo — react-loading-skeleton is web-only; for React Native you'd install react-native-skeleton-placeholder separately and write yet another parallel tree.
- A11y baked in —
aria-busy,aria-live,prefers-reduced-motion,inertfocus trap — handled. With the manual approach you wire each yourself.