Terminal
Terminal window with sequenced typing and output, a full transcript and copy.
pnpm dlx @glinui/cli@latest add terminalpnpm dlx glinui initDetected Next.js and Tailwind CSSWrote glinui.json and theme tokenspnpm dlx glinui add button cardAdded 2 components in 1.2sInstallation
pnpm dlx @glinui/cli@latest add terminalCredits. Adapted from Magic UI (MIT, (c) Magic UI). Timers and CSS instead of motion, static first render, full transcript for assistive tech, copy button, token colors and glass. Attribution details.
Prefer the package?
Usage
Improvements: no animation library, timers with cleanup and Strict Mode safety, a static first render for SSR and reduced motion, a screen-reader transcript instead of live typing, a built-in copy button, glass variant and tokenised colors.
Engines: this component drives its main animation through the pluggable motion engine. Pass `engine` (css, motion or gsap), wrap a subtree in `MotionEngineProvider`, or set `data-glin-engine` on `<html>`. The css engine is built in and dependency free; motion and gsap are opt-in via `@glinui/motion/register/*`. `motion="none"` renders the final state and `subtle` is opacity only.
Variants
Every vocabulary variant on the default tone. Omit variant to follow the ambient design style.
$ pnpm add @glinui/ui$ pnpm add @glinui/ui$ pnpm add @glinui/ui$ pnpm add @glinui/ui$ pnpm add @glinui/ui$ pnpm add @glinui/ui$ pnpm add @glinui/uiimport { AnimatedSpan, Terminal } from "@glinui/ui"
export function TerminalVariantsDemo() { return ( <div className="grid gap-4 md:grid-cols-2"> <Terminal variant="glinr" title="glinr" sequence={false} showCopy={false}><AnimatedSpan>$ pnpm add @glinui/ui</AnimatedSpan></Terminal> <Terminal variant="solid" title="solid" sequence={false} showCopy={false}><AnimatedSpan>$ pnpm add @glinui/ui</AnimatedSpan></Terminal> <Terminal variant="plain" title="plain" sequence={false} showCopy={false}><AnimatedSpan>$ pnpm add @glinui/ui</AnimatedSpan></Terminal> <Terminal variant="soft" title="soft" sequence={false} showCopy={false}><AnimatedSpan>$ pnpm add @glinui/ui</AnimatedSpan></Terminal> <Terminal variant="outline" title="outline" sequence={false} showCopy={false}><AnimatedSpan>$ pnpm add @glinui/ui</AnimatedSpan></Terminal> <Terminal variant="ghost" title="ghost" sequence={false} showCopy={false}><AnimatedSpan>$ pnpm add @glinui/ui</AnimatedSpan></Terminal> <Terminal variant="gradient" title="gradient" sequence={false} showCopy={false}><AnimatedSpan>$ pnpm add @glinui/ui</AnimatedSpan></Terminal> </div> )}No sequence
Every line starts on its own delay.
onetwo<Terminal sequence={false} showCopy={false}> <AnimatedSpan delay={200}>one</AnimatedSpan> <AnimatedSpan delay={900}>two</AnimatedSpan></Terminal>Glass (opt-in)
Glass is opt-in and needs a backdrop behind it. Switch the preview stage to Vivid or Photo to see the frosted surface.
$ pnpm buildCompiled in 1.2s<Terminal variant="glass" title="build">...</Terminal>Engine comparison
The same component on the css, motion and gsap engines. Replay restarts all three.
CSS
pnpm add @glinui/uiDone in 2sMotion
pnpm add @glinui/uiDone in 2sGSAP
pnpm add @glinui/uiDone in 2s// Same component, three engines. motion and gsap are opt-in:// import "@glinui/motion/register/motion"// import "@glinui/motion/register/gsap"<Terminal engine="css" startOnView={false}> <TypingAnimation>pnpm add @glinui/ui</TypingAnimation> <AnimatedSpan>Done in 2s</AnimatedSpan></Terminal>
<Terminal engine="motion" startOnView={false}> <TypingAnimation>pnpm add @glinui/ui</TypingAnimation> <AnimatedSpan>Done in 2s</AnimatedSpan></Terminal>
<Terminal engine="gsap" startOnView={false}> <TypingAnimation>pnpm add @glinui/ui</TypingAnimation> <AnimatedSpan>Done in 2s</AnimatedSpan></Terminal>Accessibility
- The first render, SSR and reduced motion all show the full final text.
- While animating, the visual layer is aria-hidden and a screen-reader-only transcript carries the full text, so nothing is announced character by character.
- The copy button announces the result through a polite live region.
Keyboard Interactions
| Key | Action |
|---|---|
| Tab | Reaches the copy button; the output area has no extra tab stops. |
ARIA Attributes
- `role=group` with `aria-label`
- `aria-live=off` on the animated layer
- Copy status is `role=status`
Reduced Motion
Full motion types commands and fades lines in. Subtle fades lines in without typing. None, or prefers-reduced-motion, renders the full transcript at once. Timers are cleared on unmount.
Affected properties
typingline fadecaret blinkAPI Reference
Terminal
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
variant | "glinr" | "solid" | "plain" | "soft" | "outline" | "ghost" | "gradient" | "glass" | - | ambient (glinr) | Surface variant. Omit to follow the ambient design style (glinr by default, plain for minimal, glass for glass). |
tone | "neutral" | "accent" | "success" | "warning" | "danger" | "info" | - | neutral | Colour tone for the vocabulary variants. |
title | string | - | - | Window title, also the default accessible name. |
sequence | boolean | - | true | Reveal animated children one after another. |
startOnView | boolean | - | true | Wait until the terminal is scrolled into view. |
showCopy | boolean | - | true | Show the copy button. |
copyValue | string | - | - | Copied text. Defaults to the full transcript. |
outputClassName | string | - | - | Classes for the scrolling output. |
delay | number | No | 0 | Milliseconds to wait after this line's turn before it appears. |
AnimatedSpan / TypingAnimation
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
delay | number | No | 0 | Milliseconds to wait after the item's turn. |
duration | number | - | 60 | TypingAnimation: milliseconds per character. |
children | string | ReactNode | - | - | TypingAnimation needs a string; AnimatedSpan takes any node. |
Source
Import directly from the package or browse the source on GitHub. Click any file to view it.
Import
import { Terminal } from "@glinui/ui"Dependencies
@glinui/ui@glinui/motionclass-variance-authority@phosphor-icons/reactGenerated API Snapshot
Beta
Generated API Snapshot
BetaAuto-extracted from TypeScript source in packages/ui/src/components/terminal.tsx. This section is in beta and may lag behind hand-curated docs. Regenerate with pnpm --filter @glinui/docs api:generate.
Generated: 2026-10-08T01:41:21.546Z · Full index: /docs/api-metadata
Primary Props Type
TerminalProps
AnimatedSpanProps
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
delay | number | No | 0 | Milliseconds to wait after this line's turn before it appears. |
TerminalProps
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
copyValue | string | No | - | Text copied by the button. Defaults to the full transcript. |
engine | EngineName | No | - | Engine override: `css` (default), `motion`, `gsap` or a registered custom engine. |
motion | MotionLevel | No | - | Motion override. `none` renders the static final state, `subtle` is opacity only. |
outputClassName | string | No | - | Class for the scrolling output area. |
sequence | boolean | No | true | Reveal animated children one after another. |
showCopy | boolean | No | true | Show the copy button. |
startOnView | boolean | No | true | Wait until the terminal is scrolled into view before playing. |
title | string | No | - | Window title in the chrome. |
tone | SurfaceTone | No | - | - |
variant | SurfaceVariant | "default" | "raised" | "frosted" | No | - | Visual variant. Omit for the ambient design style (glinr: lift shell, raised chrome strip, inset output well; plain: flat bordered terminal). |
TypingAnimationProps
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
as | "span" | "div" | "p" | No | "span" | - |
children | string | Yes | - | Text to type. Must be a string. |
delay | number | No | 0 | Milliseconds to wait after this line's turn before typing starts. |
duration | number | No | 60 | Milliseconds per character. |