Output Format

What boneyard generates when it snapshots your UI — the bones JSON format, where files go, and how to use them.

Generated files

Running npx boneyard-js build scans your app for named <Skeleton> components, captures bone data at each breakpoint, and writes the results to .bones.json files. A registry.js file is also generated so every skeleton can be imported in one line.

src/bones/ ← auto-created by the CLI
├── blog-card.bones.json ← from <Skeleton name="blog-card">
├── profile.bones.json
├── dashboard.bones.json
└── registry.js ← import once in your app entry

Each file contains responsive bone data captured at multiple viewport widths. Breakpoints are auto-detected from Tailwind or set in boneyard.config.json. Bones use a compact array format for smaller file sizes. The generated registry.js imports all of these automatically — just add import './bones/registry' to your app entry.

SkeletonResult

Each breakpoint inside a .bones.json file is a SkeletonResult — a flat list of positioned rectangles that mirror your real layout pixel-for-pixel.

src/bones/blog-card.bones.json
{
  "name": "blog-card",
  "viewportWidth": 375,
  "width": 343,
  "height": 284,
  "bones": [
    [0,    0,   100,  180, 8],      // hero image
    [0,    192, 69.9, 20,  4],      // title
    [0,    220, 100,  16,  4],      // excerpt
    [0,    244, 6.99, 24,  "50%"], // avatar
    [9.33, 248, 23.3, 16,  4]       // author name
  ]
}
Bone fields

Each bone is stored as a compact tuple: [x, y, w, h, r, c?]. The 6th element is optional and only present for container bones.

FieldTypeDescription
xnumberHorizontal offset as a percentage of the container width
ynumberVertical offset from the top edge in pixels
wnumberWidth as a percentage of the container width
hnumberHeight in pixels
rnumber | "50%"Border radius — a number for pixels, or "50%" for circles
ctrue (optional)Container bone flag — when true, this bone represents a container element (card, panel) and is rendered at a lighter shade so child bones stand out
Result fields

Top-level fields on each SkeletonResult object in the .bones.json file.

FieldTypeDescription
namestringIdentifier from the name prop, or 'component' by default
viewportWidthnumberBrowser viewport width at capture time (px)
widthnumberContainer element width at capture time (px)
heightnumberTotal content height (px) — used to size the skeleton overlay
bonesBone[]Flat array of positioned rectangles — every visible element as a bone
Direct API (non-React)

The React <Skeleton> wrapper calls these automatically. You can also call them directly for vanilla JS, SSR, or other frameworks.

Snapshot from a live DOM element (browser only)

ts
import { snapshotBones } from 'boneyard'

const result = snapshotBones(document.querySelector('.card'))
// result: { name, viewportWidth, width, height, bones: Bone[] }

Render bones to an HTML string (SSR / vanilla)

ts
import { renderBones } from 'boneyard'

const html = renderBones(result, '#d4d4d4')
container.innerHTML = html

The bones array is framework-agnostic — just positioned rectangles. Render them however you want, or use the React <Skeleton> wrapper which handles everything automatically.