---
title: Thinking Orb
description: A canvas-drawn indicator that a model is thinking.
category: AiReasoning
status: beta
since: 0.3.9
tags: [ai, loading, canvas]
syncStatus: reviewed
verified: true
---

## Usage

### Basic
::::TuffDemoWrapper{demo="ThinkingOrbThinkingOrbDemo" code-lang="vue"}
---
code: |
  <template>
    <TxThinkingOrb />
    <TxThinkingOrb state="searching" :size="64" />
    <TxThinkingOrb state="solving" :size="20" :display-size="14" />
  </template>
---
::::

### Best Practices

- For a new orb per thought, key the component by that thought; changing `state` won't reroll it.
- Pass an explicit `state` where you need determinism, such as screenshot tests and recordings.
- Keep `size` at `20` or `64`; use `displaySize` for any other rendered size.
- Show one orb per thought.

## API Reference

### Props

| Name | Type | Default | Description |
|------|------|---------|-------------|
| `state` | `OrbState \| 'random'` | `'random'` | Which orb to draw; `'random'` rolls once on mount and keeps it. |
| `size` | `20 \| 64` | `20` | Preset geometry size; only these two are tuned. |
| `displaySize` | `number` | same as `size` | Rendered CSS size in px; leaves the drawing parameters alone. |
| `speed` | `number` | `1` | Animation speed multiplier. |
| `paused` | `boolean` | `false` | Pauses the animation. |
| `theme` | `'auto' \| 'dark' \| 'light'` | `'auto'` | Color theme; `auto` follows the environment. |
| `label` | `string` | an English label per form | Accessible name; supply it on non-English surfaces. |

### Types

:::TuffCodeBlock{lang="typescript"}
---
code: |
  type OrbState =
    | 'working' | 'searching' | 'solving' | 'listening' | 'connecting'
    | 'weaving' | 'composing' | 'breathing' | 'shaping'
---
:::

## Overview

- Every mounted orb shares one clock (`performance.now`), so orbs on screen stay in phase.
- Drawing stops offscreen (`IntersectionObserver`) and while the tab is hidden.
- Under reduced motion, a single representative frame is drawn; it still follows theme changes.
- The canvas scales by `devicePixelRatio`, capped at 2.
- Without a canvas (jsdom, for instance), the element stays and painting is skipped without throwing.

## Technologies

- Vendored from [thinking-orbs](https://github.com/Jakubantalik/thinking-orbs) v0.2.0 (MIT © Jakub Antalik); the source headers keep the attribution.
- Source: `packages/tuffex/packages/components/src/thinking-orb/`.
