Monorepo for Tangled tangled.org

web: replace bones skeletons with skullet #4680

Merged oppi.li
targeting master from eti/skullet
Merged opened by and assigned to oppi.li
targeting master from eti/skullet

This swaps our loading skeletons from bones to skullet.

With bones, every skeleton was a JSON file of saved box positions. We had to re-capture them from Storybook whenever the UI changed, and they got stretched and off at widths they weren't captured at. Skullet draws the skeleton from the real component, filled with sample data, so it matches the page and updates itself when the UI changes.

What changed #

  • Deleted the 49 bones JSON files, the pnpm bones capture script, and the patch we carried on boneyard.
  • Pages hand their loading data straight to skullet, the way its docs show.
  • Pages rendered on the server still show the real content right away, not a skeleton.
  • The skeleton colours follow our theme, including the light/dark toggle.
  • Screen readers get a "Loading…" label on most skeletons.
  • The sample data now has the same number of rows as the real pages, so nothing jumps when the content arrives.
  • Skeletons keep the shapes of what they stand in for: hidden hover actions and copy-button states no longer draw as squares, counts inside a loading page draw once instead of twice, the profile activity chart draws its icons instead of one grey block, and the profile skeleton matches the tab being opened.
  • Code views draw one bar per line with line numbers, and the pull request skeleton draws a sample diff instead of an empty block.
  • Organizations get the organization skeleton once their profile is known, or when you've opened them before.
  • Directory pages show their skeleton: the listing streams on client navigation instead of holding the old page, and file paths still redirect to the file view.

How it compares #

I ran both versions side by side in a headless browser on 18 pages at phone, laptop and desktop widths, and paused the data so I could screenshot each skeleton next to the loaded page.

  • Skullet's skeleton looks more like the real page in 46 of 53 cases.
  • Nothing shifts when the content loads (bones had small jumps).
  • The app ships about 62 KB less JavaScript (gzipped).
  • No generated files to keep in sync anymore.

Each picture is bones' skeleton, then skullet's skeleton, then the loaded page.

Repo overview: Repo overview: bones skeleton, skullet skeleton, loaded page

Issue list: Issue list: bones skeleton, skullet skeleton, loaded page

Commit log: Commit log: bones skeleton, skullet skeleton, loaded page

Pull request: Pull request: bones skeleton, skullet skeleton, loaded page

Profile: Profile: bones skeleton, skullet skeleton, loaded page

File: File: bones skeleton, skullet skeleton, loaded page

Organization, opened a second time: Organization: bones skeleton, skullet skeleton, loaded page

Full report with videos and screenshots of every page (Tangled team only): https://claude.ai/artifact/9Ea7ioBjqpeR6aZnvdk6vh

Downsides #

  • Skeletons show up a bit later, because skullet has to draw the sample first. On a slow phone it's about half a second later than bones, and almost 2 seconds on the commit log.
  • With "reduce motion" turned on, the content jumps once when it loads. That's a bug in skullet itself.
  • The profile page loads a bit differently from the rest, because the newer pattern broke page navigation there.
  • The first time you open an organization, its skeleton has a person's profile layout, because the page doesn't know it's an organization until the profile arrives.
Commits 0