use UI

Skeleton vs Spinner

Both say “wait”, but they say it about different things. A skeleton describes the content that is coming: its shape, its size, roughly how much of it there is. A spinner only reports that something is happening somewhere. That difference decides which one belongs where — a skeleton needs a layout it can imitate, and a spinner needs a place the user is already looking.

If you know what the content will look like, draw it. If you only know that something is running, spin.

Skeleton

A low-contrast shape that occupies the same space as the content still loading, so the layout is visible before the data arrives.

Reach for it when

  • The layout is known in advance — a list of cards, a table, a profile header.
  • Loading usually takes somewhere between 300ms and a couple of seconds.
  • Several pieces of content arrive independently and you want the page to settle progressively rather than all at once.
  • You want to avoid layout shift: the skeleton reserves the exact space the content will take.

Avoid it when

  • Loads that finish under ~300ms. The skeleton flashes and reads as a glitch — render nothing instead.
  • You don't know the shape of what's coming. A skeleton that doesn't match the final layout causes the shift it was meant to prevent.
  • Waiting on an action the user just triggered, like submitting a form. A button spinner keeps the feedback attached to the thing they clicked.
  • Long or open-ended waits. After a few seconds a skeleton stops reassuring and starts looking broken — switch to a progress indicator with an explanation.

Spinner

A small looping animation shown while an operation is in flight, indicating activity but not progress.

Reach for it when

  • The wait follows a direct action — submitting a form, saving, deleting — and the spinner can sit on the control that was pressed.
  • The area is too small for a meaningful skeleton, like inside a button or next to an input.
  • You genuinely cannot predict the resulting layout, so a skeleton would guess wrong.
  • The wait is short and roughly bounded — under a couple of seconds.

Avoid it when

  • Initial page or list loads where the layout is known. A skeleton communicates more and prevents layout shift.
  • Operations that take more than a few seconds. Without progress information a spinner is indistinguishable from a hang — use a progress bar and say what is happening.
  • Several spinners on one screen. A page of rotating circles reads as chaos; prefer one region-level indicator.
  • Blocking the whole screen for something that only affects one part of it.