Dotted thought-orb loading indicators for AI & agent UIs — six tuned states, two sizes, auto dark/light
Dotted thought-orb loading indicators for AI & agent UIs — six tuned states, two sizes, auto dark/light
Dotted thought-orb loading indicators for AI & agent UIs. Nine hand-tuned animated states, each shipped at two purpose-tuned sizes, rendered on a plain 2D canvas — no WebGL, no filters, works identically in Chrome, Safari and Firefox.
Live demo · Repository · Report an issue
npm install thinking-orbsimport { ThinkingOrb } from 'thinking-orbs';
function Status() {
return ;
}Nine verbs an agent can be doing, each a distinct animation:
{/* particles on tilted orbits */}
{/* a scan meridian sweeps a dotted globe */}
{/* bands scramble, then click back solved */}
{/* a waveform rolls through the rings */}
{/* a constellation wires itself */}
{/* three strands plait around the sphere */}
{/* an undulating multi-band sash */}
{/* a ring slowly morphing */}
{/* dotted outline: circle → triangle → square */}Two tuned presets — separate designs, not a scale factor. 64 for chat-avatar scale, 20 for inline-text scale. Each carries its own dot count, dot size and speed tuning:
Strictly monochrome — light ink for dark backgrounds, dark ink for light backgrounds — with the mode picked automatically from the host project:
{/* default — detects from the project */}
{/* pin: light dots for dark backgrounds */}
{/* pin: dark dots for light backgrounds */}auto resolves in three layers and updates live when any of them change:
data-theme="dark|light" attribute or dark/light class (the Tailwind / shadcn convention), watched via MutationObserver;prefers-color-scheme, subscribed for live OS theme switches;All other `` props (className, style, data-*, …) pass through.
role="img" with a sensible per-state aria-label out of the box.prefers-reduced-motion: reduce renders a static representative frame — no animation — and still follows the live theme.IntersectionObserver) or when the tab is hidden, and resumes in phase — all instances share one clock.ctx.filter, no SVG filters, no WebGL — the same pixels everywhere, cheap on low-end devices. Device-pixel-ratio capped at 2.MIT © Jakub Antalik
No open issues yet, or sync has not completed.