Vue

Use boneyard in Nuxt, Vite, or any Vue 3 app. Same pixel-perfect skeletons, same CLI — Vue component with slots.

Quick start

1. Install

bash
npm install boneyard-js

2. Wrap your components

App.vue
<script setup>
import { ref } from 'vue'
import Skeleton from 'boneyard-js/vue'
import './bones/registry'

const loading = ref(true)
</script>

<template>
  <Skeleton name="blog-card" :loading="loading">
    <BlogCard />
  </Skeleton>
</template>

3. Generate bones

Option A — Vite plugin (recommended, no second terminal):

vite.config.ts
import { boneyardPlugin } from 'boneyard-js/vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  plugins: [vue(), boneyardPlugin()]
})

Option B — CLI:

bash
npx boneyard-js build

4. Import the registry

ts
// Add once in your app entry (e.g. main.ts)
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.

Props
PropTypeDefaultDescription
loadingbooleanShow skeleton or children
namestringResolve bones from registry by name
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)
classstringCSS class on the container
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 during CLI capture
Slots
SlotDescription
defaultYour real component — shown when not loading
#fallbackShown when loading but no bones are available
#fixtureMock content for CLI capture (dev only, never in production)
vue
<Skeleton name="dashboard" :loading="loading">
  <!-- Default: your real component -->
  <Dashboard :data="data" />

  <!-- Fixture: mock content for CLI bone capture -->
  <template #fixture>
    <Dashboard :data="mockData" />
  </template>

  <!-- Fallback: shown if no bones generated yet -->
  <template #fallback>
    <p>Loading...</p>
  </template>
</Skeleton>
Dark mode

Auto-detects via .dark class on <html> or any parent element (Tailwind convention), and prefers-color-scheme media query. Uses darkColor when dark mode is active.

Animations
ValueEffect
'pulse'Fades a lighter overlay in and out (1.8s cycle)
'shimmer'Sweeps a gradient highlight across each bone (2.4s cycle)
'solid'Static — no animation
true / falsetrue = pulse, false = solid
vue
<!-- Shimmer -->
<Skeleton name="card" :loading="true" animate="shimmer">
  <Card />
</Skeleton>

<!-- Custom colors -->
<Skeleton name="card" :loading="true" color="#fca5a5" dark-color="#7f1d1d">
  <Card />
</Skeleton>
Global defaults

Set defaults for all skeletons with configureBoneyard():

ts
import { configureBoneyard } from 'boneyard-js/vue'

configureBoneyard({
  color: '#e5e5e5',
  darkColor: 'rgba(255,255,255,0.08)',
  animate: 'shimmer',
})

Per-component props override global defaults.

Config file

See Install → Config file for the full boneyard.config.json reference. Works with all frameworks.

Next steps