React
Use boneyard in Next.js, Vite, Remix, or any React app. Wrap your components, run the CLI, and get pixel-perfect skeleton screens.
1. Install
npm install boneyard-js2. Wrap your components
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
npx boneyard-js buildAuto-detects your dev server and captures all named skeletons at multiple breakpoints.
4. Import the registry
// 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.
| Prop | Type | Default | Description |
|---|---|---|---|
| loading | boolean | — | Show skeleton or children |
| name | string | — | Unique name — generates name.bones.json |
| initialBones | ResponsiveBones | — | Pass bones directly (overrides registry) |
| color | string | rgba(0,0,0,0.08) | Bone color in light mode |
| darkColor | string | rgba(255,255,255,0.06) | Bone color in dark mode |
| animate | 'pulse' | 'shimmer' | 'solid' | pulse | Animation style (also accepts true/false) |
| className | string | — | Extra CSS class on the wrapper |
| fallback | ReactNode | — | Shown when loading but no bones available |
| fixture | ReactNode | — | Mock content for CLI capture (dev only) |
| stagger | number | boolean | false | Stagger delay between bones in ms (true = 80ms) |
| transition | number | boolean | false | Fade out duration in ms when loading ends (true = 300ms) |
| boneClass | string | — | CSS class applied to each bone element |
| snapshotConfig | SnapshotConfig | — | Controls 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.
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.
<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.
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.
// 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). Addspanif your text renders inside span wrappers.captureRoundedBorders— Setfalseif your cards use shadows instead of borders (default:true).
See CLI for all build flags, watch mode, Vite plugin, and React Native scanning. See Install for the boneyard.config.json reference.