https://framer.com/m/Spinner-R85ncS.js
Spinner
Spinner is the lightest loading loop the system has: one SVG, one CSS keyframe, no motion library, no hooks. It is SSR-safe and it stops for readers who ask for reduced motion.
Examples
Live specimens for every control the component exposes. The arc colour is never a panel setting — it inherits the current text colour, so a spinner is the right colour wherever it lands.
Default
24px across, a 2.5px stroke, a quarter-turn arc and one rotation every 0.8 seconds. The arc takes the current text colour, so it needs no colour control.
Size and thickness
Size is the diameter in px; thickness is the stroke, 0.5 to 20. Keep the stroke proportional or a large spinner reads as a ring and a small one closes up.
16 / 2
24 / 2.5
40 / 4
Arc and track
Arc is how much of the circle turns; track is the ring underneath it. A short arc reads as urgent, a long one as steady, and dropping the track to 0 leaves a bare stroke.
arc 10%
arc 75%
track 0, 1.6s
Props
The controls exposed on the instance panel. There is no colour control by design — the arc uses currentColor.
Usage
Guidance carried over from the component definition.
Reach for Spinner
Any wait short enough that a progress number would be noise — a button in flight, a panel loading.
Places where weight matters: one SVG and one keyframe, no motion library, no hooks, no effects.
Server-rendered pages — it touches no window API and renders identically on the server.
Reach for something else
A wait with a known length. Show real progress instead of an endless loop.
A button’s own pending state. Button has a loading control that handles it in place.
Skeleton loading of a whole layout. That is a placeholder pattern, not a spinner.
Io — UI Basics
Every spinner above is a live Spinner instance. The arc takes the current text colour and the animation stops when the reader asks for reduced motion.