# React Terminal Component: Tipp-Animation ohne Ruckeln

> So baust du eine React Terminal Component, die Befehle tippt, Spinner und Fortschrittsbalken zeigt, Output einfärbt, nie springt und Reduced Motion beachtet.

- Autor: [Serban Rusu](https://wingo-ui.com/blog/authors/serban), Founder of Wingo UI
- Veröffentlicht: 6. Nov. 2026
- Kategorie: [Komponenten-Guides](https://wingo-ui.com/de/blog/category/components)
- Lesezeit: 9 Min.
- Kanonische URL: https://wingo-ui.com/de/blog/react-terminal-component
- Englische Fassung: https://wingo-ui.com/blog/react-terminal-component

## Kurz gesagt

Eine gute React Terminal Component tippt jeden Befehl hinter einem Prompt, lässt einen Spinner oder Fortschrittsbalken laufen, gibt farbigen Output aus und lässt die Befehle kopieren und die Session neu abspielen. Sie legt das ganze Transkript schon im ersten Frame an, damit die Seite nie springt, hält den Text für Screenreader und Suchmaschinen lesbar und zeigt bei reduzierter Bewegung sofort die fertige Session. Das Terminal von Wingo UI (eine Pro-Komponente) erledigt all das aus einem einzigen lines-Array und steuert das Tippen über einen einzigen Motion Value, sodass React nicht für jedes Zeichen neu rendert.

Eine React Terminal Component ist das Fenster auf der Landingpage eines Dev-Tools, in dem sich `npm install` von selbst tippt, ein Spinner zum Häkchen wird und die Deploy-URL grün erscheint. Sie zeigt schneller als jeder Absatz, was eine CLI tut, und man macht dabei leicht etwas falsch: Der Hero springt, sobald Zeilen erscheinen, ein Screenreader hört nichts, die Animation läuft endlos weiter, auch für Leute, die weniger Bewegung eingestellt haben, und ein langer Befehl schiebt die Seite auf dem Smartphone zur Seite. Dieser Guide baut eine React Terminal UI, die alle vier Fehler vermeidet, mit dem [Terminal](https://wingo-ui.com/components/terminal) von Wingo UI. Wir bauen diese Bibliothek, wir sind also nicht neutral; Fakten zu anderen Projekten verlinken auf ihre Quellen und tragen ein Datum.

## Was muss eine React Terminal Component können?

Eine glaubwürdige Session zeigen, nicht im Weg stehen und lesbar bleiben. Das ist die Liste, an der wir uns orientiert haben:

- **Getippte Befehle** hinter einem Prompt, mit Block-Caret, in einem Tempo, das du einstellst.
- **Aktivität**: ein Spinner, der zu einem Häkchen wird (oder zu einem Kreuz, wenn der Schritt fehlschlägt), und ein Fortschrittsbalken, der sich bis 100 % füllt.
- **Farbiger Output**: standardmäßig gedimmt, einzelne Zeilen in den Farben für Erfolg, Warnung oder Fehler.
- **Kopieren und Replay** als Buttons, damit niemand einen Befehl abtippt oder die Seite neu lädt, um die Session noch einmal zu sehen.
- **Kein Layout Shift.** Das Fenster hat seine endgültige Höhe, bevor das erste Zeichen getippt wird.
- **Lesbar ohne JavaScript.** Das ganze Transkript steht im Server-HTML, für Crawler und Screenreader gleichermaßen.
- **Reduzierte Bewegung** zeigt sofort die fertige Session.
- **Verhalten auf dem Smartphone**: Lange Zeilen scrollen innerhalb des Fensters, nie die Seite.

## Wie fügst du ein Terminal in eine React-App ein?

Installier es mit der CLI. Sie kopiert `terminal.tsx` nach `components/ui/`, zusammen mit allem, was die Datei importiert (Button, Copy Button, Tooltip und die Motion-Helfer). Terminal ist ein Pro-Item, also meld dich vorher mit `npx wingo-ui@latest login` an:

```bash
npx wingo-ui@latest add terminal
```

Dann beschreibst du die Session als Daten. Jeder Eintrag in `lines` ist ein Schritt: ein `command` zum Tippen, optional ein Label für `spinner` oder `progress`, das `duration` ms lang läuft, und `output`-Zeilen als Strings oder als `{ text, tone }`.

```tsx
import { Terminal, type TerminalLine } from "@/components/ui/terminal"

const lines: TerminalLine[] = [
  {
    command: "npm install @acme/cli",
    spinner: "Installing @acme/cli",
    duration: 1300,
    output: [{ text: "✓ Added 1 package in 1.9s", tone: "success" }],
  },
  {
    command: "npx acme deploy --prod",
    progress: "Uploading",
    duration: 1600,
    output: [
      "Build    6.1s    214 files",
      "Region   us-east-1 (New York)",
      { text: "✓ Live at https://northwind.acme.app", tone: "success" },
    ],
  },
]

export function DeployHero() {
  return (
    <Terminal
      lines={lines}
      title="emma@macbook: ~/northwind"
      mode="dark"
      trafficLights
      className="max-w-xl"
    />
  )
}
```

Scroll die Demo ins Bild, schau zu, wie sie abläuft, und drück dann auf Replay. Probier auch den Copy-Button aus: Er kopiert beide Befehle, einen pro Zeile.

> Live-Demo (Terminal): Sieh zu, wie sich die Session selbst tippt, und drück dann auf Replay, um sie erneut abzuspielen, oder auf Kopieren, um beide Befehle mitzunehmen. Probier sie unter [Terminal](https://wingo-ui.com/components/terminal) aus und installier sie mit `npx wingo-ui@latest add terminal`.

Die wichtigsten Props: `mode="dark"` hält das Fenster auf einer hellen Seite dunkel (der klassische Hero-Look), `chrome` wählt Mac-Punkte, eine schlichte Titelleiste oder gar keinen Rahmen, `tone` oder eine beliebige CSS-Farbe in `color` färbt Prompt, Caret und Fortschrittsbalken, und `prompt` macht aus `$` ein `❯` oder `root@vps:~#`. Jeder Schritt kann seinen eigenen `prompt` und sein eigenes `delay` setzen. Soll der Copy-Button etwas anderes kopieren als die Befehle, etwa ein einzeiliges Installationsskript, gibst du es als `copyValue` mit.

## Wie zeigst du einen fehlgeschlagenen Schritt?

Setz `tone: "danger"` auf den Schritt. Der Spinner endet dann mit einem Kreuz statt mit einem Häkchen, und jede Output-Zeile kann ihren eigenen Ton haben:

```tsx
const tests: TerminalLine[] = [
  {
    command: "npm test",
    spinner: "Running 48 tests",
    tone: "danger",
    duration: 1500,
    output: [
      { text: "✓ 46 passed", tone: "success" },
      { text: "! 1 skipped   checkout/apple-pay.test.ts", tone: "warning" },
      { text: "✗ 1 failed    cart/totals.test.ts", tone: "danger" },
      "  Expected $128.40, received $128.04",
    ],
  },
]
```

Eine rote Zeile in einem Marketing-Terminal wirkt seltsam, passt aber gut in die Doku, etwa in einen Abschnitt „So sieht ein Fehler aus“, oder in einen Changelog, der einen Bug vorher und nachher zeigt.

## Wie vermeidet eine React Terminal Animation Ruckeln?

Halt React aus der Schleife heraus, die jedes Zeichen tippt. Der naheliegende Weg zu einem animierten Terminal ist ein `setInterval`, das ein Zeichen an den State anhängt. Die `TypingAnimation` von Magic UI zum Beispiel startet mit einem leeren String und ruft `setDisplayedText` einmal pro Zeichen auf, standardmäßig im Abstand von 60 ms ([Registry-Quellcode](https://magicui.design/r/terminal.json), geprüft am 6. November 2026). Für eine einzelne Überschrift ist das in Ordnung. Eine ganze Session aus Befehlen bedeutet aber mehrere Sekunden lang alle 45 bis 60 ms einen Render, und der Text steht erst im DOM, wenn er fertig getippt ist.

Das Terminal von Wingo UI geht den umgekehrten Weg. Das vollständige Transkript wird beim ersten Render angelegt. Ein einziger Motion Value hält die Uhr der Session in Millisekunden, und jede Zeile leitet ihren Zustand daraus ab: Ein Befehl deckt sich über einen `clip-path` auf, der um jeweils ein `ch` wächst, der Caret bewegt sich per Transform, und Output-Zeilen schalten ihre Opacity zum geplanten Zeitpunkt um. React rendert nur, wenn die Wiedergabe startet und endet. Weil jede Zeile von Anfang an ihren endgültigen Platz einnimmt, behält das Fenster vom ersten bis zum letzten Frame dieselbe Höhe, und der Inhalt darunter verschiebt sich nie.

Zwei weitere Regeln halten es ruhig. Mit `trigger="in-view"` (dem Standard) wartet es, bis etwa ein Drittel des Fensters zu sehen ist, damit ein Terminal unterhalb des sichtbaren Bereichs nicht fertig ist, bevor es jemand sieht. Mit `trigger="mount"` startet es, sobald die Seite hydriert ist. Mit `loop` pausiert es, solange es außerhalb des Bildschirms ist, statt Frames zu verbrennen.

## Was passiert bei reduzierter Bewegung und mit Screenreadern?

Bei `prefers-reduced-motion: reduce` zeigt das Terminal sofort das fertige Transkript und deaktiviert den Replay-Button, weil es nichts abzuspielen gibt. Es liest die Einstellung über `usePrefersReducedMotion` aus `lib/motion`, das hydration-sicher ist; warum wir nicht den Hook von motion selbst nehmen, erklären wir in [Prefers reduced motion in React](https://wingo-ui.com/de/blog/prefers-reduced-motion-react). `animate={false}` liefert bewusst dasselbe ruhige Ergebnis, zum Beispiel für ein Vorschaubild oder eine gedruckte Doku-Seite.

Für Screenreader ist das Transkript eine fokussierbare Region, deren Name aus dem `title` kommt (oder aus `labels.region`, standardmäßig „Terminal“). Zeilen, die noch nicht sichtbar sind, enthalten ihren Text trotzdem schon, also wird die ganze Session der Reihe nach vorgelesen. Prompts, Punkte, Caret und die Frames des Spinners sind `aria-hidden`, damit ein Screenreader die Befehle und den Output vorliest und nicht „Dollar“ und Braille-Punkte. Der Copy-Button meldet „Copied“ über den [Copy Button](https://wingo-ui.com/components/copy-button), auf dem er aufbaut.

Cult UI hat sich anders entschieden, und das ist ebenfalls vernünftig: Die Terminal Animation markiert den Output mit `role="log"` und `aria-live="polite"`, sodass neue Zeilen angesagt werden, sobald sie erscheinen ([Doku](https://www.cult-ui.com/docs/components/terminal-animation.md), geprüft am 6. November 2026). Das passt zu Output, den jemand selbst ausgelöst hat. Bei einem Hero, der von selbst abläuft, war uns Stille lieber als ein Screenreader, der Zeile für Zeile einen erfundenen Deploy vorliest.

## Wie verhält sich das Terminal auf dem Smartphone?

Zeilen brechen nie um, denn ein umbrochener Shell-Befehl sieht kaputt aus und lässt sich schlecht kopieren. Stattdessen scrollt der Viewport innerhalb des Fensters seitlich, mit `overscroll-x-contain`, damit ein Wischen nicht die Seite mitzieht, und Tastaturnutzer erreichen ihn per Tab und scrollen mit den Pfeiltasten. Unter 640px wird die Schrift eine Stufe kleiner (aus 12px werden 11px bei `size="sm"`, aus 13px werden 12px bei `md`), so passt eine typische `npm install`-Zeile auf einen 390px breiten Bildschirm. Copy- und Replay-Button sind normale Button-Komponenten in der kleinen Icon-Größe: Sie sehen nach 32px aus und haben bei einem groben Zeiger eine Trefferfläche von 44px.

Eine Falle: Die Tipp-Animation zählt Zeichen in `ch`, der Breite eines Monospace-Zeichens. Lass Emoji und andere breite Zeichen aus den `command`-Strings heraus; im `output` sind sie kein Problem, denn der wird nicht getippt.

## Wie steuerst du die Wiedergabe mit deinem eigenen Button?

Gib `playing` und `onPlayingChange` mit. Mit `defaultPlaying={false}` wartet das Fenster mit leerem Prompt, bis du es startest, und `onComplete` feuert jedes Mal, wenn eine Session zu Ende ist:

```tsx
"use client"

import { useState } from "react"
import { Button } from "@/components/ui/button"
import { Terminal, type TerminalLine } from "@/components/ui/terminal"

export function RunDeploy({ lines }: { lines: TerminalLine[] }) {
  const [playing, setPlaying] = useState(false)
  return (
    <div className="flex flex-col gap-3">
      <Terminal
        lines={lines}
        defaultPlaying={false}
        playing={playing}
        onPlayingChange={setPlaying}
        showReplay={false}
      />
      <Button variant="soft" onClick={() => setPlaying((value) => !value)}>
        {playing ? "Pausieren" : "Deploy starten"}
      </Button>
    </div>
  )
}
```

`onPlayingChange(false)` kommt am Ende einer Session ohne Loop an, also springt die Beschriftung des Buttons von selbst zurück.

## Welche Terminal-Komponenten gibt es für shadcn-Projekte?

shadcn/ui selbst hat keine, eine shadcn terminal component kommt also aus einer fremden Registry oder von npm. Das zeigten Doku, Quellcode und npm-Seiten am 6. November 2026:

| Komponente | Installation | Spinner / Fortschritt | Kopieren, Replay | Reduzierte Bewegung |
|---|---|---|---|---|
| [Magic UI Terminal](https://magicui.design/docs/components/terminal) | shadcn-Registry, `@magicui/terminal` | Nein | Nein | Im Quellcode nicht behandelt |
| [Cult UI Terminal Animation](https://www.cult-ui.com/docs/components/terminal-animation.md) | shadcn-Registry, `@cult-ui/terminal-animation` | Nein | Ein Refresh-Button in der Demo, kein Kopieren | In der Doku nicht erwähnt |
| [react-animated-term](https://github.com/dongy7/react-animated-term) | npm, letztes Release 2.0.0 (Februar 2021) | Spinner über `frames` | Nein | Nicht erwähnt |
| Wingo UI Terminal | `npx wingo-ui@latest add terminal` | Beides | Beides | Zeigt das fertige Transkript |

Wo die anderen die bessere Wahl sind: Magic UI und Cult UI sind kostenlos und MIT-lizenziert, das Terminal von Wingo UI ist es nicht. Magic UI setzt beliebiges JSX als Zeile ein, praktisch für eigenen Output. Cult UI bringt Szenarien in Tabs mit (etwa Tabs für npm, pnpm und yarn) und eine Option für ein Hintergrundbild. react-animated-term ist eine schlichte npm-Abhängigkeit ohne Registry, falls du mit einem Paket leben kannst, das seit 2021 kein Release mehr bekommen hat.

## Wann sind ein Code Block oder eine Textanimation die bessere Wahl?

Wenn die Leser mit dem Text etwas tun sollen. Ein animiertes Terminal ist eine Demo; die Schritte einer Setup-Anleitung gehören in einen statischen, hervorgehobenen [Code Block](https://wingo-ui.com/components/code-block) mit Copy-Button, und der ist kostenlos:

```tsx
import { CodeBlock } from "@/components/ui/code-block"

export function InstallStep() {
  return <CodeBlock code="npx wingo-ui@latest add terminal" language="bash" filename="Terminal" showLineNumbers={false} />
}
```

> Live-Demo (Code Block): Ein hervorgehobenes Snippet mit Dateiname im Header und Copy-Button: Markier den Text oder drück auf Kopieren. Probier sie unter [Code Block](https://wingo-ui.com/components/code-block) aus und installier sie mit `npx wingo-ui@latest add code-block`.

Und wenn sich nur eine Überschrift selbst tippen soll, ist ein ganzes Fenster zu viel. [Text Animate](https://wingo-ui.com/components/text-animate) mit `effect="typewriter"` tippt einen einzelnen String mit Caret, hält das Element über `as` ein echtes `h1` und liest Screenreadern den ganzen Satz einmal vor.

Ist die Ausgabe echt, also live aus einem Build oder von einem Server, lass die Animation ganz weg. Unser [Guide zum React Log Viewer](https://wingo-ui.com/de/blog/react-log-viewer) zeigt stattdessen Live-Zeilen mit Filtern nach Level und einem Follow-Modus.

## Wo passt ein Terminal auf eine Landingpage?

In den Hero, neben die Überschrift, oder in ein Band „So funktioniert es“ direkt darunter. Bleib bei zwei oder drei Schritten; eine Session, die länger als etwa acht Sekunden läuft, verliert die Leser vor der entscheidenden Zeile. Setz den echten Installationsbefehl in der Nähe in einen Code Block oder eine Copy-Pill, damit niemand auf die Animation warten muss, um ihn zu kopieren. Unser [Guide zur shadcn Hero Section](https://wingo-ui.com/de/blog/shadcn-hero-section) behandelt die Layouts drumherum.

Wenn du eine ganze Seite für eine Entwicklerplattform baust, hat die [Vorlage Developers Page](https://wingo-ui.com/templates/developers-page) schon einen Code-Hero mit Sprach-Tabs, Karten für die API-Oberfläche, einen Endpoint-Explorer und ein CLI-Terminal, das Deploy- und Webhook-Zeilen abspielt, sobald es ins Bild scrollt.

Weitere Guides dieser Art findest du in der [Kategorie Komponenten-Guides](https://wingo-ui.com/de/blog/category/components), angefangen mit dem Pillar-Artikel zu [React-Formularkomponenten](https://wingo-ui.com/de/blog/react-form-components-guide).

## Nächster Schritt

Öffne die [Doku zum Terminal](https://wingo-ui.com/components/terminal), probier im Playground `chrome`, `tone`, `speed` und `loop` aus und installier es dann mit `npx wingo-ui@latest add terminal`. Terminal und die Developers Page gehören zu Wingo UI Pro ([Preise](https://wingo-ui.com/de/pricing)); Code Block und Copy Button sind mit einem kostenlosen Konto frei.

## Komponenten in diesem Artikel

- [Terminal](https://wingo-ui.com/components/terminal) (Pro): An animated React terminal window for dev-tool landing pages and docs: typed commands, output, spinners and progress bars. Installation: `npx wingo-ui@latest add terminal`
- [Code Block](https://wingo-ui.com/components/code-block) (Free): A React code block with syntax highlighting, line numbers, highlighted lines and a copy button, themed from a single accent color. Installation: `npx wingo-ui@latest add code-block`
- [Copy Button](https://wingo-ui.com/components/copy-button) (Free): A React copy to clipboard button for IBANs, tax IDs, links and API keys: an icon button with a tooltip, a labelled button and CopyText. Installation: `npx wingo-ui@latest add copy-button`
- [Text Animate](https://wingo-ui.com/components/text-animate) (Pro): Animated text for headlines and copy that reveals by word, character or line with a fade, blur, slide, scale or typewriter effect. Installation: `npx wingo-ui@latest add text-animate`
- [Developers Page](https://wingo-ui.com/templates/developers-page) (Pro): A React developer platform page template: a code hero with language tabs, API surfaces, a live CLI terminal, endpoints, uptime and limits. Installation: `npx wingo-ui@latest add developers-page`

## Häufige Fragen

### Wie baue ich ein animiertes Terminal in React?

Beschreib die Session als Daten (jeder Schritt ein Befehl, optional ein Spinner oder Fortschrittsbalken, dazu Output-Zeilen) und lass eine Komponente sie auf einer Zeitachse abspielen. Mit Wingo UI heißt das npx wingo-ui@latest add terminal und ein lines-Array, das du an die Terminal-Komponente gibst.

### Hat shadcn/ui eine Terminal-Komponente?

Nein. Stand 6. November 2026 steht in der Komponentenliste von shadcn/ui kein Terminal. Magic UI und Cult UI veröffentlichen Terminal-Komponenten über die shadcn-Registry, und Wingo UI installiert sein Terminal als Quellcode über die eigene CLI.

### Ist ein animiertes Terminal schlecht für die Barrierefreiheit?

Das kann es sein. Text, der Zeichen für Zeichen entsteht, wird in Bruchstücken oder gar nicht vorgelesen, und Bewegung stört manche Leser. Render den vollen Text von Anfang an, deck ihn nur visuell auf und lass die Animation bei prefers-reduced-motion weg.

### Soll ich für Installationsbefehle ein Terminal oder einen Code Block nehmen?

Nimm einen Code Block, wenn Leute einen Befehl lesen und kopieren sollen, und ein Terminal, wenn du zeigen willst, was nach dem Ausführen passiert. Eine Doku-Seite kann beides nutzen: den Code Block in den Setup-Schritten, das Terminal im Hero.

### Ist das Terminal von Wingo UI kostenlos?

Nein, Terminal gehört zu Wingo UI Pro ($8 im Monat, $80 im Jahr oder einmalig $150). Code Block und Copy Button, mit denen es sich gut kombinieren lässt, sind mit einem kostenlosen Konto frei.

---

Quelle: https://wingo-ui.com/de/blog/react-terminal-component
