🦴 Skullet

Skullet for Phoenix LiveView

Your own component, rendered from sample data and measured, so the skeleton is exactly the shape of what is coming. Nothing moves when it arrives. Every demo below runs on a real assign_async.

Every demo above

`hold` waits 150ms before a skeleton shows; with a 600ms latency it is up for about 450ms before the reveal — and a reveal over a shown skeleton animates.

Skeletons

Every one of these is your markup, drawn once from sample data while the assign is loading.

From your component

The sample is a person; the real data is someone else. The skeleton is measured from the sample, the reveal is measured from the real card.

Loading profile

Ada Lovelace

Mathematician, first to see the machine as more than arithmetic.

code
<Skullet.skeleton :let={user} id="card" async={@user} sample={@sample_user}>
  <Profile.card user={user} />
</Skullet.skeleton>

Changing size

The sample guesses one line, four arrive: the reveal eases to the real height instead of snapping.

Loading

Ada Lovelace

One line of sample.

Plain children

You drive `loading` yourself; the children are measured as they are.

Grace Hopper

Rear admiral, compiler pioneer, found the first literal bug.

Your own skeleton

A chart does not measure well. The `skeleton` slot supplies the shape instead: a baseline and a row of boxes.

Loading

Hints

Marking what measuring reads wrong: `skullet-ignore` leaves an element out, `skullet-block` draws it whole.

Loading

Ada Lovelace New

Mathematician, first to see the machine as more than arithmetic.

Memory

Pass `remember` and the next skeleton is drawn from the data this one last showed, not from the sample. Replay once, then reload the page.

Loading

Grace Hopper

Rear admiral, compiler pioneer, found the first literal bug.

Reveals

How content replaces its skeleton. smart decides from how long the skeleton was up, recent input, refetches and how much arrives.

Reveal modes

Pick a mode and replay. Every mode is measured the same way; only the exit differs.

Loading

Ada Lovelace

Mathematician, first to see the machine as more than arithmetic.

Your own reveal

`registerReveal` in app.js names a spec: this one wipes the content in behind a mask, 500ms.

Loading

Ada Lovelace

Mathematician, first to see the machine as more than arithmetic.

Empty states

The result arrived empty, which is neither loading nor an error: `empty` swaps in the `empty_message` slot, and the reveal measures that message like any other content.

Loading

Ada Lovelace

Sample line one, as long as a typical message.

Grace Hopper

Sample line two, a little longer than the first.

Katherine Johnson

Sample line three.

Suspense and failure

The same component is the Suspense boundary: an async assign, a measured fallback, one error branch. This one always fails, and Retry replays it.

Loading profile

Styling

Every option is a custom property, so the panel above is enough: one provider, and every skeleton inside inherits it.

Theming

Colours follow the page's colour scheme; the reveal's shape, timings and enter filters are properties too.

Loading

Ada Lovelace

Mathematician, first to see the machine as more than arithmetic.

A provider's mode

`mode` sets `color-scheme` on the wrapper, and the palette the bars are drawn from is that wrapper's, not the page's. This card is dark on a light page because it says so, and it flips on its own without the page moving.

the page around it stays as it is
Loading

Ada Lovelace

Mathematician, first to see the machine as more than arithmetic.

Reference

The parts you do not see in the demos.

Images

An image still decoding when the content arrives waits at zero opacity and fades in. These four are served with a delay.

Loading
ABCD

Accessibility

A loading reveal is aria-busy, its skeleton is hidden from screen readers, and the label is read in its place. Reduced motion stops the shimmer and makes every reveal instant.

Turn on “Reduce motion” in your system settings and reload: the bars hold still and content appears at once.

Debugging

Add ?skullet-debug to the URL: blue outlines while loading, green when the content landed where the skeleton was, red with the distance when it moved. `skullet-xray` on any element shows the sample through the skeleton.

The footer shows the running engine — state, phase, bars drawn, and whether anything threw.

Server rendering

The whole page is rendered on the server, skeleton included. `<Skullet.Boot.boot />` in the root layout paints it before the first paint, so the bundle never has to arrive first.

View source: the sample is in the HTML, and an inline script measures it.

engine