Learned skeletons
Measure the real layout once, remember it, and paint it on every load after — no build step, nothing to regenerate.
A measured skeleton is only available once the markup it measures has rendered — which is never the case at the moment you actually need it. Give a layout a name and skelly closes that gap: it measures the real content when it appears, keeps the result, and replays it the next time that layout is loading.
Why not snapshot at build time
Because a snapshot is a copy, and copies drift. A build-time artifact needs a headless browser, a CLI pass, and the discipline to re-run it every time markup changes — and when someone forgets, the skeleton is quietly wrong with nothing to signal it.
A learned layout is overwritten by the next successful render. Edit the component and the correction happens the first time anyone looks at it. There is no artifact to regenerate and no command to remember.
Per breakpoint
Layouts are stored per viewport bucket — 0, 480, 768, 1024, 1280, 1536 by default, overridable with breakpoints. A layout learned on a desktop is never replayed on a phone; each width learns itself the first time someone visits at that size.
Seeding the first visit
A brand-new visitor has learned nothing yet, so they get the generic skeleton. To give them the real one, export what your own browser learned, commit it, and render it from the server with <SkellySpecs> — the layouts ship in the HTML, and each browser replaces them with its own measurements as it goes.
Where layouts live
In localStorage under skelly:learned:v1, capped at 120 entries with the oldest evicted first. Pass storage to use a different store, or storage: nullto keep everything in memory for the page’s lifetime. Nothing leaves the browser.