Gooey Orb
Liquid blob whose edges “boil” with SVG noise and displacement.
Idle
State
Speed
Size
Color
From
To
SVG filtersZero deps
SVG filters · zero deps
Liquid blob whose edges “boil” with SVG noise and displacement.
Liquid blob whose edges “boil” with SVG noise and displacement.
Every orb implements the same contract, so they are interchangeable: swap the import and keep the props.
| Prop | Type | Default | Description |
|---|---|---|---|
| state | 'idle' | 'connecting' | 'listening' | 'thinking' | 'speaking' | 'error' | 'disabled' | 'idle' | Assistant lifecycle state driving the animation. error and disabled are optional extensions. |
| size | number | 160-184 (per orb) | Diameter of the orb in pixels, also exposed as the --orb-size CSS variable. |
| speed | number | 1 | Animation speed multiplier, also exposed as the --orb-speed CSS variable. |
| colorFrom | string | per-orb gradient start | Gradient start color (any CSS color), exposed as --orb-color-from. |
| colorTo | string | per-orb gradient end | Gradient end color (any CSS color), exposed as --orb-color-to. |
| levelRef | RefObject<number> | undefined | Live audio amplitude in 0..1 read every frame without re-render; a negative value falls back to the procedural animation. |
| label | string | 'Assistant orb' | Accessible name announced by screen readers via aria-label. |
| className | string | undefined | Extra class names merged onto the root element. |
| ref | Ref<HTMLDivElement> | undefined | React 19 ref to the root element for measuring, animating or scrolling into view. |
Copy the component files from the playground above, then render the orb with its default configuration.
import { GooeyOrb } from '@/registry/orbe/gooey-orb/gooey-orb';
export const Assistant = () => (
<GooeyOrb
state="idle"
size={168}
speed={1}
colorFrom="#f472b6"
colorTo="#8b5cf6"
/>
);
Drive state from your assistant lifecycle and pass a levelRef with the live amplitude. The bundled useAudioLevel hook opens the microphone and writes a 0..1 level into the ref every frame without re-rendering; while the value is negative the orb falls back to its procedural animation.
'use client';
import { useState } from 'react';
import type { OrbState } from '@/registry/lib/orb-state';
import { useAudioLevel } from '@/registry/lib/use-audio-level';
import { GooeyOrb } from '@/registry/orbe/gooey-orb/gooey-orb';
export const Assistant = () => {
const [state, setState] = useState<OrbState>('idle');
const { levelRef } = useAudioLevel(state === 'listening');
return <GooeyOrb state={state} levelRef={levelRef} />;
};