React Terminal Component: Tipp-Animation ohne Ruckeln
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 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:
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 }.
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.
$ npx wingo-ui@latest add terminalDie 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:
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 (opens in a new tab), 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. 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, 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 (opens in a new tab), 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:
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:
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 mit Copy-Button, und der ist kostenlos:
$ npx wingo-ui@latest add code-blockUnd wenn sich nur eine Überschrift selbst tippen soll, ist ein ganzes Fenster zu viel. 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 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 behandelt die Layouts drumherum.
Wenn du eine ganze Seite für eine Entwicklerplattform baust, hat die Vorlage 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, angefangen mit dem Pillar-Artikel zu React-Formularkomponenten.
Nächster Schritt
Öffne die Doku zum 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); Code Block und Copy Button sind mit einem kostenlosen Konto frei.
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.
- Komponenten
- React
- Animation
- Landingpage
- Doku


