A CLAUDE.md is just a markdown file at the root of your repo. Copy the content below into your own project's CLAUDE.md to give your agent the same context.
npx versuz@latest install 0xgf-boneyard --kind=claude-mdcurl -o CLAUDE.md https://raw.githubusercontent.com/0xGF/boneyard/HEAD/CLAUDE.md# Boneyard
Skeleton screen generator that snapshots real UI into positioned rectangles ("bones").
## Project structure
- `packages/boneyard/` — core library (React component, CLI, extraction logic)
- `src/react.tsx` — `<Skeleton>` React component
- `src/extract.ts` — DOM walker that captures bones (handles `leafTags`, `excludeTags`, etc.)
- `src/shared.ts` — bone registry, animation constants (SHIMMER, PULSE, DEFAULTS)
- `src/types.ts` — `SnapshotConfig`, `BoneData`, etc.
- `bin/cli.js` — CLI entry point (`boneyard-js build`)
- `apps/docs/` — Next.js docs site (Turbopack)
- `src/bones/` — generated `.bones.json` files + `registry.js`
- `src/app/overview/` — landing page with hero demo
- `src/app/demo/` — interactive skeleton demos
## Key concepts
- **Bones**: flat arrays `[x%, y, w%, h, borderRadius, isContainer?]` — positions are relative to the skeleton container.
- **Registry**: `registry.js` is auto-generated by the CLI. Import it once in your app entry and `<Skeleton name="...">` auto-resolves.
- **Fixtures**: a `fixture` prop provides alternate markup for the CLI to snapshot instead of real children. Useful when real data isn't available at build time.
- **leafTags**: `snapshotConfig={{ leafTags: ["section"] }}` tells the extractor to treat those tags as atomic — no recursion into children. This prevents internal elements (text, icons, bars) from becoming separate bones.
- **Priority**: explicit `initialBones` prop > registry lookup by `name` > fixture fallback.
- **Build mode**: CLI sets `window.__BONEYARD_BUILD = true`, component renders `fixture ?? children`, CLI snapshots the DOM, writes bones JSON.
- **Config**: `boneyard.config.json` is the primary customization point. Runtime options (`color`, `darkColor`, `animate`, `shimmerColor`, `speed`, etc.) are baked into the generated `registry.js` via `configureBoneyard()`. Per-component props override config.
- **Dark mode**: detected via `.dark` class on `<html>` or ancestor. Does NOT use `prefers-color-scheme` — gives app developer explicit control.
- **Container bones**: bones with `c: true` are skipped during rendering. They represent parent backgrounds and would cause opacity overlap if rendered alongside child bones.
- **Animation constants**: centralized in `shared.ts` (SHIMMER, PULSE, DEFAULTS). All frameworks import from there. Users override via `boneyard.config.json`, not by editing constants.
## CLI usage
```bash
# From repo root — run against a running dev server
node packages/boneyard/bin/cli.js build http://localhost:PORT --out apps/docs/src/bones
# Defaults: scans all pages, uses breakpoints from config or 375/768/1280
# --force to regenerate unchanged skeletons
# Bones are hashed — only changed skeletons are rewritten
```
## Common tasks
### Regenerating bones for the docs site
1. Make sure the docs dev server is running (`cd apps/docs && pnpm dev`)
2. From repo root: `node packages/boneyard/bin/cli.js build http://localhost:<PORT> --out apps/docs/src/bones`
3. The CLI auto-crawls all pages, finds `<Skeleton>` components, and writes bones JSON + registry.
### Adding a new demo skeleton
1. Create the real UI component and a fixture (if needed)
2. Wrap in `<Skeleton name="my-name" loading={true} fixture={<MyFixture />} snapshotConfig={{ leafTags: [...] }}>`
3. Run the CLI to generate bones
4. Import `./bones/registry` in layout if not already done
## Build
```bash
# Build the package
pnpm --filter boneyard run build
# Build docs
pnpm --filter boneyard-docs run build
# Run tests
pnpm --filter boneyard-js run test
```
## Publishing
Package is published to npm as `boneyard-js`. Version is in `packages/boneyard/package.json`.