Getting started

Quick Start

One package, zero native code. The bundler picks the right build automatically: Metro for React Native, Webpack/Vite for web.

1. Install

npm install react-zero-skeleton
# or
yarn add react-zero-skeleton

2. Wrap your component

import { withSkeleton } from 'react-zero-skeleton'
function ArticleCard({ article }) {
return (
<div>
<img src={article.cover} style={{ height: 160 }} />
<p style={{ fontWeight: 600, width: 'fit-content' }}>{article.title}</p>
<p style={{ color: '#888', width: 'fit-content' }}>{article.excerpt}</p>
</div>
)
}
// Step 1: wrap once
export default withSkeleton(ArticleCard)

3. Pass one or two props

// Step 2: two props wherever you use it
<ArticleCard hasSkeleton isLoading={isLoading} article={data} />
// Shorthand: activates hasSkeleton + isLoading at once
<ArticleCard isLoadingSkeleton article={data} />
One prop or two?
isLoadingSkeleton={isLoading}

The shorthand. One prop, wired to your loading boolean: shows the skeleton while loading and the real UI once done. Reach for this in the common case.

hasSkeleton isLoading={isLoading}

hasSkeleton opts the component into skeleton mode (a capability you can keep always on), while isLoading drives the toggle. Use it when skeleton support is declared separately from the loading state: e.g. hasSkeleton set by a parent, isLoading from a hook. Most examples here use this form.

4. (Optional) Global theme

import { SkeletonTheme } from 'react-zero-skeleton'
// Step 3 (optional): global config for your whole app
export default function App() {
return (
<SkeletonTheme
animation="wave"
color="var(--border)"
highlightColor="var(--surface-2)"
borderRadius={6}
>
<YourApp />
</SkeletonTheme>
)
}

Animations

// Per-component override
<ArticleCard
hasSkeleton
isLoading={isLoading}
skeletonConfig={{ animation: 'shatter' }}
article={data}
/>
// Available animations
// 'pulse' : soft opacity fade (default)
// 'wave' : shimmer left to right
// 'shiver' : intense wave, wider amplitude
// 'shatter': grid fragmentation with stagger
// 'slide' : bones float up and fade
// 'beat' : double heartbeat pulse
// 'drip' : vertical shimmer cascading top to bottom
// 'none' : static placeholder
React Native only: wave and shiver require a LinearGradient peer. Install expo-linear-gradient or react-native-linear-gradient. Both are auto-detected, no config needed. On web, CSS gradients are used instead.
MIT License · github.com/J-Ben/skelter