# Teleprompter
URL: https://remocn.dev/docs/captions/components/caption-teleprompter

The whole transcript scrolls smoothly through a short window with the current line centred, past lines fading above and the next line waiting below

- Install: `npx shadcn@latest add @remocn/caption-teleprompter`
- Vibe: clean
- Natural length: transcript-driven

## Installation

```bash
npx shadcn@latest add @remocn/caption-teleprompter
```

## Usage

`CaptionTeleprompter` turns the transcript into lines — the same paging every
caption style uses, with `combineTokensWithinMilliseconds` setting how much
speech one line holds — and stacks all of them in a window `visibleLines` tall.
As each line starts, the stack glides so that line sits in the middle of the
window. Inside the current line, words the voice has not reached yet are
dimmed to `upcomingOpacity`; the lines above and below rest at `pastOpacity`
and `futureOpacity`, and the window fades out at its top and bottom edges.

Nothing ever leaves the screen: the teleprompter stays for the whole
transcript, so `holdMs` only decides how long a silence must be to start a new
line. The window takes the width you give it and wraps long lines, so place it
inside a container with the width you want — see
[Positioning](/docs/captions/getting-started/positioning) and
[Get a transcript](/docs/captions/getting-started/get-a-transcript).

```tsx
import { AbsoluteFill } from "remotion";
import { CaptionTeleprompter } from "@/components/remocn/caption-teleprompter";
import captions from "./captions.json";

export const MyScene = () => (
  <AbsoluteFill
    style={{
      justifyContent: "center",
      alignItems: "stretch",
      paddingInline: 192,
    }}
  >
    <CaptionTeleprompter captions={captions} />
  </AbsoluteFill>
);
```

## Props

| Prop | Type | Default | Description |
|---|---|---|---|
| `captions` | `Caption[]` | `—` | The timed transcript, in the `Caption` shape from `@remotion/captions`. Times are relative to the start of the surrounding `Sequence`. |
| `visibleLines` | `number` | `3` | Height of the window, in lines. The current line always sits in the middle. |
| `pastOpacity` | `number` | `0.35` | Opacity of lines that have already been spoken. |
| `futureOpacity` | `number` | `0.35` | Opacity of lines still to come. |
| `upcomingOpacity` | `number` | `0.55` | Opacity of words in the current line that the voice has not reached yet. |
| `combineTokensWithinMilliseconds` | `number` | `1500` | How much speech one line may span before the next word starts a new line. Lines also break at the end of a sentence and on any pause of at least `holdMs` (300 ms minimum). |
| `holdMs` | `number` | `600` | The pause length that starts a new line. Lines never fade out — the teleprompter stays on screen for the whole transcript. |
| `fontSize` | `number` | `64` | Font size in pixels. |
| `fontWeight` | `number` | `800` | Font weight. The font itself is inherited. |
| `color` | `string` | `"#ffffff"` | Text colour. |
| `shadow` | `boolean` | `true` | A tight text shadow that keeps the caption legible over bright footage. |
| `className` | `string` | `—` | Classes for the window — width, font family, `uppercase`. |

## Use when
- The speech is long and continuous — an explainer, a talk, a narrated walkthrough — and the viewer benefits from seeing the line before and the line after.
- You want calm, reading-first captions that never cut or pop, only glide from one line to the next.

## Don't use when
- You want one phrase at a time that replaces the last — use `caption-subtitle` for broadcast-style pages or `caption-slot` for a one-line roll.
- The captions should feel energetic and social — use `caption-karaoke` or `caption-highlight-box`.
- There is no voiceover and the text is scripted — use `word-stream`.