react-loading-skeleton

Animated React skeleton screens that automatically adapt to your app's fonts, sizing, and layout.

Library
npm
v3.5.0
4,210 stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
43 /100 Fair
Development Activity 0
Maintenance 20
Community 52
Maturity 60
Momentum 40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
76 /100 Good
Architecture 80
Code Quality 78
Innovation 55
Learning Curve 90

react-loading-skeleton gives React apps a Skeleton component that stands in for content while it loads, sized automatically to match the font size, line height, and layout of whatever it replaces. Instead of hand-crafting a separate placeholder screen for every view, developers drop <Skeleton /> directly where real content will go — inside a heading, a paragraph, a card — and it renders a correctly-proportioned animated bar without extra CSS.

A SkeletonTheme context provider lets teams set base and highlight colors, animation duration, and direction once for an entire subtree, while individual Skeleton instances can still override any of those values, or supply a custom wrapper component to control layout around repeated lines. The library ships as CSS custom-property-driven markup with a small companion stylesheet, keeping the runtime footprint minimal while remaining fully themeable.

What You Get

  • A Skeleton component that renders one or more animated placeholder lines, with a count prop supporting fractional values for partial last lines
  • A SkeletonTheme context provider for setting base color, highlight color, animation duration/direction, and other style defaults across a whole subtree
  • Per-instance overrides for width, height, border radius, circular shapes, and a custom customHighlightBackground gradient
  • A wrapper prop for wrapping each generated skeleton line in a custom component, useful for grid or card layouts
  • CSS custom-property-based styling shipped as a small companion stylesheet (dist/skeleton.css), keeping bundle size minimal
  • TypeScript type definitions for SkeletonProps and SkeletonThemeProps out of the box

Common Use Cases

  • Rendering blog post or article placeholders where the title loads before the body, each showing its own skeleton independently
  • Building skeleton states for dashboard cards, tables, and lists where the number of rows is dynamic (count prop)
  • Applying a consistent brand theme (colors, animation speed) across every loading skeleton in an app via a single SkeletonTheme wrapper
  • Showing circular avatar placeholders in user profile or comment lists using the circle prop
  • Disabling the shimmer animation and rendering a static solid-color placeholder when an error occurs instead of a loading state

Under The Hood

Architecture

The library is intentionally small and flat: Skeleton.tsx contains the single rendering component, SkeletonTheme.tsx and SkeletonThemeContext.ts implement a React Context provider for shared style defaults, and SkeletonStyleProps.ts defines the shared style-option shape both consume. Skeleton merges three layers of style precedence — context defaults, explicit props, and a raw style object — into a single set of CSS custom properties (--base-color, --highlight-color, --animation-duration, etc.) applied to plain <span> elements, so no runtime CSS-in-JS engine is involved. Fractional count values are handled by rendering full-width skeleton lines plus one narrower final line computed via calc(), and the whole group is wrapped in a container <span> carrying aria-live/aria-busy attributes for accessibility. There is no internal state, no reducers, and no side effects beyond reading context — a change to the core abstraction would mean changing how style options are merged in this one function. Tech Stack Written in TypeScript and built with tsc plus Rollup (via rollup.config.js and @rollup/plugin-typescript) into ESM and CommonJS bundles declared through package.json exports, with a separate CSS asset copied into dist/. Development uses Vite and @vitejs/plugin-react-swc for fast local iteration and Storybook 7 (with addon-essentials/interactions/links) for interactive component documentation. The only runtime dependency is a peerDependency on react (>=16.8.0); there is no runtime dependency on ReactDOM APIs beyond what React itself requires. Code Quality Tests run under Vitest with @testing-library/react and jsdom, covering rendering counts, style precedence (props vs. context vs. style object), circular skeletons, fractional counts, and theme propagation — a meaningful, focused test suite for a small component library rather than an exhaustive one. Linting is enforced via ESLint with the Airbnb TypeScript config plus eslint-plugin-react/react-hooks/jsx-a11y, Prettier formatting, and a Husky pre-commit hook running lint-staged so unformatted or unlinted code cannot be committed. Types are strict TypeScript throughout with no any usage observed in the core files. API Design The public API is deliberately minimal: one component (Skeleton), one context provider (SkeletonTheme), and a shared style-props interface, all importable from a single entry point (import Skeleton, { SkeletonTheme } from 'react-loading-skeleton'). Getting started requires no configuration beyond importing the component and its stylesheet, and prop names (baseColor, highlightColor, circle, count) map directly to visible behavior with sensible defaults, which keeps the learning curve very low for a first-time integrator.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers