Skip to content
Docs

Command palette

Jump to a page or view, or find a todo by name.

Changelog

Skullet is the only way to draw a loading skeleton

Every web loading skeleton goes through MeasuredSkeleton, and a test refuses hand-made pulse boxes, the shadcn Skeleton, other skeleton libraries and skeletons on public pages.

Markdown

Since 2026-11-04 every loading state in the signed-in web app has been measured from a sample of the component it stands in for, with skullet. That is now a rule, stated in AGENTS.md, CODING_STANDARDS.md and on Design patterns: a loading skeleton is MeasuredSkeleton from @/platform/skeleton/measured-skeleton, fed data and a sample from the feature's <feature>.samples.ts. Only platform/skeleton/ imports skullet.

scripts/web-skeletons.test.mjs runs in pnpm test. It fails when apps/web/src or packages/ui/src imports skullet outside the wrapper, when app code imports a *Skeleton* component from a package (the shadcn Skeleton, SidebarMenuSkeleton, a UI kit's), when a feature or route draws an animate-pulse box with a muted fill, and when either package.json lists another skeleton library such as react-loading-skeleton or react-content-loader. It also walks the imports of every route outside routes/_auth/ and fails if one reaches the wrapper, so the skullet chunk stays off public pages, as the first-paint rule (W15) requires. A public page renders its data from the route loader, or a Spinner for a pending action. The Enforcement page and the Review checklist list the new check.

The shadcn skeleton.tsx stays in packages/ui, because the vendored sidebar and the ReUI emoji picker draw their own loading state with it. Skullet has no React Native build, so the Expo app keeps its SkeletonRows placeholder.

Edit on GitHubDocumentation is in English.
Cookie settings
We use essential cookies to make our app work. With your consent, we also use optional cookies to improve your experience.

Read our Cookie Policy and Privacy Policy.