Component

Live Captions

A rolling caption overlay for meeting and video surfaces. Shows the last N cue lines in a translucent dark bubble, with speaker names and live interim transcription rendered dimmed while speech is still in flight.

Single line

A minimal caption display with maxLines=1 — useful for subtitle-style overlays.

the bottleneck is review capacity

Two speakers

When speaker is set, a muted prefix identifies who is talking. Multiple speakers scroll naturally within the window.

Maya: the bottleneck is review capacity

Alex: agreed, let me pull up the dashboard

Interim vs final

Non-final cues (where final is false) are rendered dimmed and italic to signal they may still change. Click "Finalise cue" to see the transition.

Maya: the bottleneck is review capacity

Alex: agreed, let me pull up

The second line is interim (non-final) — dimmed and italic while speech is in flight.

Installation

$pnpm add @refraction-ui/react

Usage

tsx
import { LiveCaptions } from '@refraction-ui/react'

const cues = [
  { id: '1', speaker: 'Maya', text: 'the bottleneck is review capacity', final: true },
  { id: '2', speaker: 'Alex', text: 'agreed, let me pull up the dashboard', final: false },
]

export function MeetingView() {
  return (
    <div className="relative">
      <video src="..." />
      <LiveCaptions
        cues={cues}
        maxLines={2}
        position="absolute"
        className="bottom-4 inset-x-4"
      />
    </div>
  )
}

LiveCaptions props

PropTypeDefaultDescription
cuesCaptionCue[]--The full ordered list of caption cues to track.
maxLinesnumber2Maximum number of cue lines to display at once.
position'static' | 'absolute''static'How the container is placed in the layout. Use 'absolute' to overlay a video element.
classNamestring--Additional CSS classes to apply to the caption container.

CaptionCue shape

PropTypeDefaultDescription
idstring--Unique identifier for this cue (used as React key).
speakerstring--Speaker name — shown as a muted prefix when present.
textstring--The caption text for this cue.
finalboolean--Whether this cue is finalised. Non-final (interim) cues are rendered dimmed and italic.