React

Use boneyard in Next.js, Vite, Remix, or any React app. Wrap your components, run the CLI, and get pixel-perfect skeleton screens.

Quick start

1. Install

bash
npm install boneyard-js

2. Wrap your components

tsx
import { Skeleton } from 'boneyard-js/react'

function BlogPage() {
  const { data, isLoading } = useFetch('/api/post')
  return (
    <Skeleton name="blog-card" loading={isLoading}>
      <BlogCard data={data} />
    </Skeleton>
  )
}

3. Generate bones

bash
npx boneyard-js build

Auto-detects your dev server and captures all named skeletons at multiple breakpoints.

4. Import the registry

tsx
// Add once in your app entry (e.g. layout.tsx, _app.tsx, main.tsx)
import './bones/registry'

This import is required.Without it, skeletons won't render — the Skeleton component needs the registry to resolve bone data by name. Import it once at the top level of your app.

Props
PropTypeDefaultDescription
loadingbooleanShow skeleton or children
namestringUnique name — generates name.bones.json
initialBonesResponsiveBonesPass bones directly (overrides registry)
colorstringrgba(0,0,0,0.08)Bone color in light mode
darkColorstringrgba(255,255,255,0.06)Bone color in dark mode
animate'pulse' | 'shimmer' | 'solid'pulseAnimation style (also accepts true/false)
classNamestringExtra CSS class on the wrapper
fallbackReactNodeShown when loading but no bones available
fixtureReactNodeMock content for CLI capture (dev only)
staggernumber | booleanfalseStagger delay between bones in ms (true = 80ms)
transitionnumber | booleanfalseFade out duration in ms when loading ends (true = 300ms)
boneClassstringCSS class applied to each bone element
snapshotConfigSnapshotConfigControls bone extraction (see Hiding elements)

fixture prop

Use fixtureto provide mock content for the CLI when real data isn't available (auth-protected pages, user-specific data, API-dependent content). Only rendered during npx boneyard-js build — never in production.

Hiding elements from the skeleton

Sometimes you don't want everything to show up in the skeleton. Maybe you have icons, decorative elements, or a live widget that should always be visible. You can tell boneyard to skip them.

Pass a snapshotConfig prop to control what gets included:

Skip specific elements by CSS class or attribute

Use excludeSelectors — any CSS selector works. The element and everything inside it gets ignored.

example
<Skeleton
  name="dashboard"
  loading={isLoading}
  initialBones={dashBones}
  snapshotConfig={{
    excludeSelectors: [
      '.icon',                     // skip all icons
      '[data-no-skeleton]',         // skip anything with this attribute
      'svg',                        // skip all SVGs
    ]
  }}
>

Skip entire HTML tags

Use excludeTagsto skip every instance of a tag type. Good for nav bars and footers that shouldn't be part of the skeleton.

tsx
snapshotConfig={{
  excludeTags: ['nav', 'footer', 'aside']
}}

Mark elements in your JSX

The easiest way — add data-no-skeleton to any element you want to exclude from bone capture, then exclude it. Note: this only affects capture — the element is still hidden at runtime. Place elements outside the Skeleton wrapper to keep them visible during loading.

your-component.tsx
// No bone will be generated for this element during capture
<div data-no-skeleton>
  <LiveChart />
</div>

// Then in your Skeleton wrapper
snapshotConfig={{ excludeSelectors: ['[data-no-skeleton]'] }}

Other snapshot options

  • leafTags — Tags treated as one solid block (default: p, h1–h6, li, tr). Add span if your text renders inside span wrappers.
  • captureRoundedBorders — Set false if your cards use shadows instead of borders (default: true).
CLI & Vite plugin

See CLI for all build flags, watch mode, Vite plugin, and React Native scanning. See Install for the boneyard.config.json reference.