History

Changelog

All notable changes to react-zero-skeleton. Follows semantic versioning.

v3.0.0latest2026-07-01

Mobile skeleton lifecycle improvements

featAdd `useSkeleton` hook: Core hook for skeleton state management on mobile. Provides `isSkeletonVisible` and `bones` to components for proper lifecycle handling.
fixImprove exit behavior on mobile: `exit` prop with `fadeUp`, `fadeDown`, `fadeLeft`, `fadeRight` ensures smooth skeleton dismissal across platforms.
fixAdd `revealOnExit` on mobile: Real content becomes visible during exit animation, preventing white flash on mobile devices during transition.
fixEnter animations on mobile: Fade-in variants ensure skeletons appear smoothly instead of instant pop-in on initial load.
example
import { SkeletonTheme } from 'react-zero-skeleton'

export default function App() {
  return (
    <SkeletonTheme
      exit="fadeUp"
      revealOnExit
      color="#e4e4e7"
    >
      <YourApp />
    </SkeletonTheme>
  )
}
v2.0.02026-06-24

SkeletonDevTools

featNew SkeletonDevTools: a floating in-app panel to inspect skeleton match quality on web and React Native. Drag it anywhere, dock left/right/float, dark/light theme.
featPer-component quality score (fidelity / waste / coverage / stability), averaged into a global X/5 score on the floating button.
featX-ray mode: see the skeleton overlay and the real content at once, on any component, without touching isLoading.
featWaste overlay: highlights bone area not covered by real visual content (purple) vs. genuinely empty containers (yellow), per component.
featForce-load (all components at once) to preview the loading state on demand, no need to wire a fake isLoading.
featAvailable via `react-zero-skeleton/devtools` : separate entry point, dev-only, tree-shaken out of production builds when unused.
fixInspection overlay legend is now anchored to the real component's rendered height instead of the skeleton's estimated height, fixing overlap on components taller than their skeleton.
example
import { SkeletonDevTools } from 'react-zero-skeleton/devtools'

export default function App() {
  return (
    <SkeletonDevTools>
      <YourApp />
    </SkeletonDevTools>
  )
}
v1.2.12026-06-09

npm discoverability

fixExpanded npm keywords for better discoverability: skeleton-loader, content-placeholder, expo, nextjs, typescript, adaptive, network-aware, auto-skeleton.
v1.2.02026-06-07

Adaptive animation

featNew adaptive animation: pick the skeleton animation from device and connection signals. Skelter detects nothing itself: bring your own source (NetInfo, navigator.connection, expo-battery…) and feed the values.
featNew `conditions` field on SkeletonTheme and skeletonConfig: network, battery, saveData, deviceTier, charging, reducedMotion, Platform.OS, or any custom signal.
featNew `adaptive` policy: a declarative `when → use` rule matrix (AND within a rule, first match wins) or a function of conditions. The resolved animation overrides `animation`.
featReduced-motion accessibility still forces a static skeleton regardless of the adaptive result. Pure, zero-dependency, works on web and React Native.
example
<SkeletonTheme
  animation="shatter"          // used when no rule matches
  conditions={{ network, battery, saveData }}
  adaptive={[
    { when: { network: ['slow-2g', '2g'] }, use: 'none'  },
    { when: { saveData: true },             use: 'pulse' },
    { when: { batteryBelow: 0.2 },          use: 'pulse' },
    { when: { network: '3g' },              use: 'wave'  },
  ]}
>
v1.1.02026-06-05

SkeletonParagraph

featNew SkeletonParagraph: wrap a block of text so it skeletons into several lines instead of one solid block. Body lines get a naturally ragged width and the last line is shortened, like real text.
featLine count via `size` presets (sm = 2, md = 3, lg = 5) or an exact `lines={n}`.
featAlignment via `align` (left / center / right), inherited from the wrapped component’s text-align when omitted, so the shortened last line sits on the correct side.
featNew mode="words": each line is split into word-sized bones separated by gaps. All widths are deterministic (no flicker). Works on web and React Native (iOS / Android).
example
<SkeletonParagraph size="md">      {/* 3 ragged lines */}
  <Text>{article.body}</Text>
</SkeletonParagraph>

<SkeletonParagraph lines={5} mode="words" align="center" />
v1.0.22026-06-02

SkeletonBox, SkeletonIgnore & shaker

featNew SkeletonBox: wrap containers that are meaningful shapes (stat cards, chips, badges). The box renders as a semi-transparent bone (opacity 0.25, static) with its children bones on top, so the skeleton shows the framed structure. Pass `static` to keep the box bone unanimated.
featNew SkeletonIgnore: wrap elements that should never receive a bone and stay visible during loading (section headers, timestamps, static labels). The measurement layer skips the element and all its descendants.
featNew shaker animation: a rapid horizontal vibration burst followed by a long rest, like a nervous tremor. Works on web (CSS keyframes) and React Native (Animated).
fixcascade on web now staggers the per-bone animation start (bone.y × cascade ms) to match native behaviour, instead of only fading bones in progressively.
example
<SkeletonTheme animation="shaker" cascade={3}>
  <SkeletonBox>            {/* faint box + child bones on top */}
    <Stat label="Steps" value="5,700" />
  </SkeletonBox>
  <SkeletonIgnore>        {/* stays visible, no bone */}
    <SectionTitle>Activity</SectionTitle>
  </SkeletonIgnore>
</SkeletonTheme>
v1.0.02026-06-01

Cascade mode

featNew cascade option: bones animate sequentially top-to-bottom based on their vertical position. Each bone's animation is delayed by bone.y × cascade ms. Works with all animation modes (pulse, beat, slide, wave, shiver, drip, shatter). cascade={3} means a bone at y=100 starts 300ms after y=0.
featcascade is available on SkeletonTheme (global) and skeletonConfig (per-component). Default: 0 (all bones animate simultaneously, existing behaviour preserved).
example
<SkeletonTheme animation="beat" cascade={3} color="#27272a" highlightColor="#3f3f46">
  <ProfileCard hasSkeleton isLoading={loading} />
</SkeletonTheme>
v0.9.02026-05-24

Drip animation + React Native New Architecture

featNew drip animation: a vertical shimmer that sweeps top to bottom with each bone phase-shifted independently, creating a cascading drip effect.
fixReact Native New Architecture (Fabric, RN 0.81+) fully supported. The fiber walker now reads fiber.type.uiViewClassName for host components and handles the Fabric stateNode layout, so auto-measurement works on both Old and New Architecture.
fixEliminated one-frame flash of placeholder content when reloading: the skeleton now appears synchronously in the same render cycle that isLoading flips back to true.
example
<SkeletonTheme animation="drip" revealOnExit color="#3f3f46" highlightColor="#71717a">
  <Card hasSkeleton isLoading={loading} />
</SkeletonTheme>
v0.8.02026-05-24

Beat animation

featNew beat animation: a double heartbeat pattern combining scale and opacity. Two quick pulses (stronger then softer) followed by a long rest, matching a real cardiac rhythm. Works on web and React Native.
example
<SkeletonTheme animation="beat" color="#3f3f46">
  <Card hasSkeleton isLoading={loading} />
</SkeletonTheme>
v0.7.02026-05-23

Enter animation + revealOnExit

featNew enter option: skeleton animates in when it re-appears after content was previously shown. Skipped on first load to avoid a flash. Five styles: 'fade', 'fadeUp', 'fadeDown', 'fadeLeft', 'fadeRight'.
featNew revealOnExit option: real content becomes visible underneath the skeleton while the exit animation plays, so the skeleton fades out revealing the content simultaneously.
example
<SkeletonTheme
  animation="shatter"
  enter="fade"
  exit="fadeUp"
  revealOnExit
>
  <Card hasSkeleton isLoading={loading} />
</SkeletonTheme>
v0.6.02026-05-21

Slide animation

featNew slide animation: bones float up 6 px and fade in/out in a smooth breathing loop. Works on web and React Native.
example
<SkeletonTheme animation="slide">
  <Card hasSkeleton isLoading={loading} />
</SkeletonTheme>
v0.5.12026-05-19

Exit animation fix

fixBones now stay visible during the exit phase instead of disappearing instantly before the animation completes.
v0.5.02026-05-18

Exit animations

featNew exit option: skeletons now animate out instead of disappearing abruptly. Default is 'fade' (300 ms opacity).
featFive exit styles: 'fade', 'fadeUp', 'fadeDown', 'fadeLeft', 'fadeRight'. Set 'none' to restore instant-removal.
featConfigurable at every level: SkeletonTheme, skeletonConfig prop, or globally via DEFAULT_SKELETON_CONFIG. Real content appears only after exit completes.
example
// Per theme
<SkeletonTheme animation="wave" exit="fadeUp">
  <Card hasSkeleton isLoading={loading} />
</SkeletonTheme>

// Per component
<Card
  hasSkeleton
  isLoading={loading}
  skeletonConfig={{ exit: 'fadeDown' }}
/>
v0.4.32026-05-17

cellSize: uniform shatter fragmentation

featNew cellSize in ShatterConfig: fixed physical cell size in px. Every bone fragments with identically-sized squares regardless of its own width.
fixgridSize is now optional. Provide cellSize alone for uniform cells; gridSize is ignored when cellSize is set.
example
<SkeletonTheme
  animation="shatter"
  shatterConfig={{ cellSize: 32, fadeStyle: 'radial', stagger: 20 }}
>
  <Card hasSkeleton isLoading={loading} />
</SkeletonTheme>
v0.4.22026-05-14

Web polish

featText bones now match actual text width (fit-content) instead of stretching to the full container.
fixSSR hydration mismatch resolved, skeleton overlay is client-only with correct server/client HTML parity.
fixResizeObserver now updates bones correctly on container resize.
v0.4.02026-05-10

Shatter animation + speed control

featNew shatter animation: grid fragmentation with three fade styles: 'random', 'cascade', 'radial'.
featNew speed option: 'slow' (0.5×), 'normal' (1×), 'rapid' (2×) or any custom numeric multiplier.
featFlashList support via the react-native adapter.
v0.3.02026-05-01

Per-element measurement

featmeasureStrategy: 'auto' walks the React Fiber tree and generates one bone per leaf element, replacing the single-block approach of v0.2.
featminDuration: skeleton stays visible for at least N ms, preventing a flash on fast connections.
featSkeletonTheme can now be nested, child themes inherit and override parent values.
featexclude option on withSkeleton: skip specific component displayNames during tree walk.
v0.2.02026-04-20

Wave, shiver & RTL

featNew wave animation: shimmer flowing left to right.
featNew shiver animation: intense rapid shimmer.
featdirection: 'rtl' reverses shimmer direction for right-to-left layouts.
feathighlightColor option: customize shimmer peak color independently from base color.
v0.1.02026-04-10

Initial release

featwithSkeleton HOC: wrap any component with one line to get an automatic skeleton.
featSkeletonTheme provider: configure color, animation, borderRadius globally.
featpulse animation: soft fade in/out on all bones.
featWeb (React) and React Native adapters.
featResizeObserver-based layout measurement: bones reflow automatically on resize.
example
import { withSkeleton, SkeletonTheme } from 'react-zero-skeleton'

const ArticleCard = withSkeleton(ArticleCardBase)

export default function Feed({ loading, articles }) {
  return (
    <SkeletonTheme animation="pulse" color="#E0E0E0">
      {articles.map(a => (
        <ArticleCard key={a.id} hasSkeleton isLoading={loading} data={a} />
      ))}
    </SkeletonTheme>
  )
}