# Voice interrupt animation in React Native: barge-in UI

> By Lawrence Arya, Founder & CEO of VP0. Published 2026-06-10. 10 min read.
> Source: https://vp0.com/blogs/voice-interrupt-animation-react-native

Barge-in is the moment a user talks over the assistant. The orb reacts, the audio stops, and the UI hands off to listening, all without a beat.

**TL;DR.** A voice interrupt animation is the moment a voice assistant UI handles a user talking over it: the speaking orb reacts, the assistant stops, and the interface shifts into listening. The build is Reanimated driving an animated shape from live audio levels, plus a clean state machine that swaps between speaking and listening the instant an interrupt is detected. The animation is the easy half; making the transition feel immediate is the real work, so starting from a free VP0 design and letting Claude Code or Cursor read its source page gets the states right before you wire the audio.

A voice interrupt animation is the moment a voice assistant UI handles a user talking over it: the speaking orb or waveform reacts, the assistant stops, and the interface shifts into listening. The build is [Reanimated](https://docs.swmansion.com/react-native-reanimated/) driving an animated shape from live audio levels, plus a clean state machine that swaps between speaking and listening the instant an interrupt is detected. The animation is the easy half; making the transition feel immediate and unambiguous is the real work, which is why starting from a free VP0 design and letting Claude Code or Cursor read its source page gets the states right before you wire the audio.

The whole point of barge-in is that the user should never wonder whether they were heard. If your assistant keeps talking for half a second after someone interrupts, the animation has failed regardless of how smooth the waveform looks. The sections below cover the states, the animated shape, and the interrupt itself.

## What is a voice interrupt animation?

It is the visual feedback for barge-in, the ability to interrupt an assistant while it is speaking. When the user starts talking, the assistant should stop its own audio and visibly switch from speaking to listening, and the animation is what makes that switch legible. Without it, a user who interrupts is left unsure whether the app noticed, so they repeat themselves or give up.

The animation usually centers on one shape, an orb or a waveform, that means different things in different states: it pulses with the assistant's own speech while speaking, then snaps to reacting to the user's voice while listening. Reanimated runs the shape on the UI thread so it tracks audio smoothly, and a state machine decides which mode the shape is in. The same audio-reactive shape appears in [a Dynamic Island music visualizer](/blogs/dynamic-island-music-visualizer-react-native/), where amplitude drives the bars.

## The four states of a voice interface

A voice UI is clearest when it has a small number of explicit states, and an interrupt-capable assistant needs four. Naming them and animating the transitions between them is what makes the interface readable.

- **Idle**, where the shape is calm and the app is waiting for the user to start.
- **Speaking**, where the shape animates to the assistant's own audio output, so the user sees the app is talking.
- **Listening**, where the shape reacts to the user's microphone input, confirming it hears them.
- **Interrupting**, the brief transition where the user barges in: the assistant's audio cuts, and the shape hands off from speaking to listening.

The interrupting state is the one most implementations skip, and it is the one that matters most here. Treating barge-in as an instant, animated handoff rather than a hard cut is what makes the assistant feel responsive instead of rude or broken. For the recording side of listening, [an audio waveform recorder UI](/blogs/audio-waveform-recorder-ui-react-native/) covers visualizing mic input in detail.

## Building the animated orb from audio levels

The core is a shape whose size or waveform tracks an audio amplitude value. You feed the current audio level into a Reanimated shared value, and an animated style maps it to scale or to the heights of waveform bars, so the shape breathes with the sound.

```jsx
const amplitude = useSharedValue(0);

// update amplitude from audio metering, smoothed so it does not jitter
function onMeter(level) {
  amplitude.value = withTiming(level, { duration: 80 });
}

const orbStyle = useAnimatedStyle(() => ({
  transform: [{ scale: 1 + amplitude.value * 0.4 }],
  opacity: 0.6 + amplitude.value * 0.4,
}));
```

The smoothing matters as much as the mapping. Raw audio metering is jittery, so animating directly to each reading makes the shape vibrate unpleasantly; a short `withTiming` between values gives it a natural ease. Keep the scale range modest, a forty percent growth at peak reads as alive without looking frantic. Because the amplitude is a shared value and the style is a worklet, the whole thing runs on the UI thread and stays smooth even while the JavaScript thread handles audio and networking. A spatial variant of audio-reactive visuals is covered in [a spatial audio soundscape UI](/blogs/spatial-audio-soundscape-ui-react-native/).

## Detecting the interrupt and switching states

The interrupt is where most of the logic lives. While the assistant is speaking, you keep the microphone active and watch its input level; when the user's voice crosses a threshold for a brief moment, that is a barge-in, and three things happen at once: the assistant's audio stops, the state flips to listening, and the shape transitions to reacting to the user.

```jsx
function onUserAudio(level) {
  if (state.value === "speaking" && level > INTERRUPT_THRESHOLD) {
    runOnJS(stopAssistantAudio)();      // cut playback immediately
    runOnJS(setState)("listening");     // flip the UI state
  }
}
```

The detail that makes or breaks it is stopping the assistant's audio immediately. The state change and animation run from the audio callback, so the JavaScript actions, cutting playback and updating React state, go through `runOnJS`. Using a brief threshold-crossing rather than a single loud sample avoids false triggers from a cough or background noise. Microphone access for this comes through the audio APIs in [Expo](https://docs.expo.dev/versions/latest/sdk/audio/), and on-device speech recognition through libraries like [react-native-voice](https://github.com/react-native-voice/voice), which has more than 2,000 stars, when you need the words and not just the level.

## Making it smooth with AI and a real design

AI builders get the orb animation quickly and the state machine wrong. Claude Code and Cursor will produce a believable audio-reactive shape, then forget the interrupting state entirely, so the assistant talks over the user, or they call playback and state functions directly from the audio worklet without `runOnJS`, which crashes. The animation looks right and the interaction is broken.

A real design and explicit states fix most of it. When the four states and their transitions are already drawn, the model implements the handoff instead of inventing a two-state version that cannot barge in, and you spend your time tuning the threshold and the smoothing. Starting from a free VP0 design gives that structure, since each design has a machine-readable source page Claude Code, Cursor, or Rork read from a pasted link. For a fuller real-time stack, [an Agora live audio room UI kit](/blogs/agora-live-audio-room-ui-kit-react-native/) shows how the audio transport layer fits under a voice interface.

## Common voice interrupt mistakes

A handful of mistakes recur in voice UIs. Skipping the interrupting state is the first and worst, leaving an assistant that cannot be interrupted, which feels unresponsive the moment a user tries to talk over it. Not stopping the assistant's audio fast enough is the second, where the app flips the UI to listening but keeps playing, so the user hears the assistant and themselves at once.

Animating to raw, unsmoothed audio levels is the third, producing a shape that vibrates and jitters rather than breathing. Calling JavaScript from the audio worklet without `runOnJS` is the fourth, which compiles and then crashes on the first interrupt. The fifth is a too-sensitive threshold that triggers on background noise, cutting the assistant off mid-sentence for no reason; tune it to a brief, clear crossing rather than a single sample.

A sixth one is easy to miss because it does not break the build: relying on audio and animation alone. A voice-only interface excludes users who are deaf or hard of hearing, and a pretty orb conveys nothing to a VoiceOver user. Pair the animation with a text alternative, show the assistant's spoken words as captions, surface the recognized user text, and announce state changes like "Listening" to the screen reader. The animation should be the polish on an interface that also works in text, not the only way to follow the conversation. Building that in from the start is far easier than retrofitting it.

## When a simpler indicator is enough

Not every voice feature needs a full audio-reactive orb. For a simple voice-note button or a push-to-talk control where the user is not conversing with an assistant, a pulsing dot or a basic recording indicator communicates everything needed with far less work, and there is no interrupt to handle because the user is in control of when to speak.

The full four-state animation earns its place when the app is a genuine back-and-forth assistant, where the user and the assistant trade turns and barge-in is part of the experience. That is when the interrupting state and the smooth audio-reactive shape pay off. Matching the complexity to whether the interaction is a conversation or a simple recording keeps you from over-building a button, and it keeps the simple cases genuinely simple rather than wrapped in machinery they never use.

## Key takeaways: a voice interrupt that feels responsive

Model the voice UI as four explicit states, idle, speaking, listening, and interrupting, and treat barge-in as an animated handoff, not a hard cut. Drive the orb or waveform from a smoothed audio amplitude in a Reanimated shared value so it breathes rather than jitters, and on interrupt, stop the assistant's audio immediately, flip the state, and transition the shape, all through `runOnJS` from the audio callback. Tune the threshold to avoid false triggers. Let an AI builder implement it from a real design, then add the interrupting state it tends to skip. A commissioned voice interface can cost $5,000 or more, while starting from a free VP0 design costs only the time you spend tuning the feel.

You can [browse VP0 designs](/explore) to start your voice UI from a real layout rather than a blank screen.

## Frequently asked questions

### How do you build a voice interrupt animation in React Native?

Drive an orb or waveform from a smoothed audio amplitude in a Reanimated shared value, and model the UI as four states: idle, speaking, listening, and interrupting. While the assistant speaks, watch the microphone level, and when the user's voice crosses a threshold, stop the assistant's audio immediately, flip to listening, and transition the shape, all through `runOnJS`. Starting from a free VP0 design gets the states and layout right so you can focus on the audio handling.

### What is barge-in and why does it need its own state?

Barge-in is the ability to interrupt an assistant while it is speaking. It needs its own state because the transition has to do three things at once: cut the assistant's audio, switch the UI to listening, and visibly hand the animation from speaking to reacting to the user. Treating it as an explicit animated handoff rather than a hard cut is what makes the assistant feel responsive instead of unresponsive or rude when someone talks over it.

### How do I keep the audio-reactive animation smooth?

Smooth the audio level before animating to it. Raw metering is jittery, so animating directly to each reading makes the shape vibrate; a short `withTiming` between values gives a natural ease. Keep the amplitude in a Reanimated shared value and map it in a worklet so the animation runs on the UI thread and stays smooth even while the JavaScript thread handles audio and networking. A modest scale range reads as alive without looking frantic.

### Can VP0 provide a free React Native template for a voice UI?

Yes. VP0 is a free iOS app design library where every design has a machine-readable source page an AI builder reads from a pasted link, with React Native and SwiftUI variants. You start from the voice interface design, with its states already drawn, hand its source to Claude Code, Cursor, or Rork, and wire the audio and Reanimated animation on top, rather than inventing the states from a blank prompt.

### What common errors happen when vibe coding a voice interrupt?

The frequent ones are skipping the interrupting state so the assistant cannot be interrupted, not stopping playback fast enough so the user hears both voices, animating to raw unsmoothed audio so the shape jitters, calling JavaScript from the audio worklet without `runOnJS` so it crashes, and a threshold so sensitive it triggers on background noise. The fixes are an explicit interrupting state, immediate audio stop, smoothed amplitude, `runOnJS` for callbacks, and a tuned threshold.

## Frequently asked questions

### How do you build a voice interrupt animation in React Native?

Drive an orb or waveform from a smoothed audio amplitude in a Reanimated shared value, and model the UI as four states: idle, speaking, listening, and interrupting. While the assistant speaks, watch the microphone level, and when the user's voice crosses a threshold, stop the assistant's audio immediately, flip to listening, and transition the shape, all through runOnJS. Starting from a free VP0 design gets the states and layout right so you can focus on the audio handling.

### What is barge-in and why does it need its own state?

Barge-in is the ability to interrupt an assistant while it is speaking. It needs its own state because the transition has to do three things at once: cut the assistant's audio, switch the UI to listening, and visibly hand the animation from speaking to reacting to the user. Treating it as an explicit animated handoff rather than a hard cut is what makes the assistant feel responsive instead of unresponsive or rude when someone talks over it.

### How do I keep the audio-reactive animation smooth?

Smooth the audio level before animating to it. Raw metering is jittery, so animating directly to each reading makes the shape vibrate; a short withTiming between values gives a natural ease. Keep the amplitude in a Reanimated shared value and map it in a worklet so the animation runs on the UI thread and stays smooth even while the JavaScript thread handles audio and networking. A modest scale range reads as alive without looking frantic.

### Can VP0 provide a free React Native template for a voice UI?

Yes. VP0 is a free iOS app design library where every design has a machine-readable source page an AI builder reads from a pasted link, with React Native and SwiftUI variants. You start from the voice interface design, with its states already drawn, hand its source to Claude Code, Cursor, or Rork, and wire the audio and Reanimated animation on top, rather than inventing the states from a blank prompt.

### What common errors happen when vibe coding a voice interrupt?

The frequent ones are skipping the interrupting state so the assistant cannot be interrupted, not stopping playback fast enough so the user hears both voices, animating to raw unsmoothed audio so the shape jitters, calling JavaScript from the audio worklet without runOnJS so it crashes, and a threshold so sensitive it triggers on background noise. The fixes are an explicit interrupting state, immediate audio stop, smoothed amplitude, runOnJS for callbacks, and a tuned threshold.

---
*Published on the [VP0 Journal](https://vp0.com/blogs). Free to read, index and cite with attribution.*
