Voice orb

Free · MITReact Native · Expo

A sphere of drifting color lobes for voice modes: idle, listening, thinking and speaking each move differently, it swells with the audio level, and a halo pulses behind it.

View as Markdown
Try it on your phone
Scan to open this demo in your phone's browser and use it with your fingers.

Installation

$ npx shadcn@latest add https://goodui.dev/native/r/voice-orb.json

Then run npx expo install --fix so react-native-reanimated, react-native-svg match your Expo SDK. Files land in components/goodui-native/voice-orb.

Usage

import { VoiceOrb } from "@/components/goodui-native/voice-orb/voice-orb";

<VoiceOrb mode={speaking ? "speaking" : "listening"} size={210} />

// With a real recorder meter, in a shared value from 0 to 1:
<VoiceOrb mode="listening" level={meter} />

When to use

Use it for
  • A voice conversation screen.
  • A calm hero for an empty AI chat, at a small size in idle.
Reach for something else
  • Scrubbing or showing recorded audio: use a waveform.
  • Plain loading states: use a spinner.

API reference

PropTypeDefault
mode*"idle" | "listening" | "thinking" | "speaking"—
size
Diameter in points.
number220
level
Your recorder's meter, 0 to 1. Without it the orb synthesizes a believable level on the UI thread.
SharedValue<number>—
colors
Hue pair of the orb. Defaults to the accent and its soft tint.
[string, string]—
paused
Stops the frame callback, for an orb that is mounted but off screen.
booleanfalse
labelsPartial<VoiceOrbLabels>—
style
Style for the outer container.
StyleProp<ViewStyle>—
testID
Identifier for end-to-end tests.
string—

Motion and haptics

  • Each mode has its own spin speed and level curve, computed in one frame callback.
  • Without `level` it synthesizes a level, so the motion is then not a real measure of the audio.
  • Reduced motion: the lobes stop and the scale holds. A `level` you pass still shows as opacity.
  • One frame callback on the UI thread, with no React re-renders. Idle runs at a third of the frame rate, reduced motion stops it, and `paused` stops it for an orb that is mounted but off screen.

Accessibility

  • Read as an image labeled with the mode, in a polite live region so mode changes are announced.

Notes for AI

  • Pass `level` from your recorder or player when you have one.
  • The default colors come from the accent. Pass `colors` for a persona.
  • The box is 1.45 times `size` so the halo has room.
  • Show captions beside it: the orb does not carry what was said.