For the complete documentation index, see llms.txt. Markdown variants are available by appending .md to any URL or sending an Accept: text/markdown header. The asciicn agent skill, for building any ASCII effect on the engine, is at /.well-known/agent-skills/asciicn/SKILL.md.

Terminal window

A terminal window framed in box-drawing glyphs that plays a scripted session: typed commands, streamed output, spinners, block progress bars and coloured ok, warn and error lines.

Controls
Speed1x
Loop
Frame
Size
Frame colour

Installation

pnpm dlx shadcn@latest add https://asciicn.dev/r/terminal-window.json

Usage

import { TerminalWindow } from "@/components/asciicn/terminal-window";
import type { TerminalStep } from "@/components/asciicn/terminal-window";
 
const script: TerminalStep[] = [
  { kind: "command", text: "pnpm test" },
  { kind: "task", text: "Running 128 tests", duration: 1.5 },
  { kind: "output", text: "128 passed", tone: "ok" },
];
 
export function TestRun() {
  return <TerminalWindow script={script} title="~/acme — test" rows={8} />;
}

Leave script out to play the built-in session: npx shadcn add installs a component, retries once after a registry timeout, fills a progress bar, lists the files it wrote, builds the site and prints a frame of a torus in the standard ramp.

A script is a list of steps, each with a kind:

  • command: typed after the prompt one key at a time, with a small, repeatable jitter between keys, then entered.
  • output: printed a line at a time. tone colours it and sets the mark before it: ok (✔), info (›), warn (!), error (✖), muted or plain. Set wrap: false to clip long lines, for ASCII art, and alt to say what the art is to screen readers.
  • task: a Loader spinner for duration seconds, then a result mark. result is ok, warn or error, and done replaces the text when it ends.
  • progress: a ProgressBar in brackets that fills from 0 to 100% over duration seconds, as in [████████░░] 82%. It stalls and spurts like a real install.
  • wait: a pause with nothing printed.

After the last step a prompt waits with a blinking █ cursor. With loop, the session starts over 3.5 seconds later.

The window is rows lines tall and never changes size. New lines push older ones off the top, and long commands wrap.

Examples

Custom script

A deploy that fails a check, retries with the check skipped, uploads and goes live. Twelve rows, the light frame and size="md".

Landing hero

The default session at 1.25x speed with a headline. They sit side by side once the container is 760px wide, and stack below that.

Props

PropTypeDefault
script

The session to play. Steps are command, output, task, progress and wait.

Type: readonly TerminalStep[]Default DEFAULT_TERMINAL_SCRIPT
title

Text in the title bar, such as a path or a command. Also names the window for screen readers.

Type: stringDefault "~/acme — zsh"
speed

Playback speed multiplier.

Type: numberDefault 1
loop

Start over 3.5 seconds after the end. When false, the button in the bottom border becomes replay.

Type: booleanDefault true
rows

Height of the screen in lines.

Type: numberDefault 18
prompt

The prompt before each command.

Type: stringDefault "$"
frame

Box-drawing set for the window frame.

Type: "light" | "heavy" | "double" | "rounded" | "ascii"Default "rounded"
color

Frame colour, a palette name or any CSS colour.

Type: AsciiColorDefault "grey"
size

Glyph cell height: 12, 14 or 16px.

Type: "sm" | "md" | "lg"Default "lg"
cell

Glyph cell height in CSS pixels. Overrides size.

Type: numberDefault –

TerminalWindow also takes the AsciiBox props shadow, filled, padding and labelAlign, and any div attribute.

Notes

  • The screen is hidden from screen readers, because it changes many times a second. A visually hidden transcript of the whole session sits next to it, and the window is a group named by title.
  • The clock runs only while the window is on screen and the tab is visible, so the session starts when the visitor scrolls to it.
  • The bottom border holds a pause button, which turns into play when paused and into replay when a session without loop ends. It is a real button, reachable with Tab.
  • With reduced motion, the window shows the finished session as one still frame, with a steady cursor and no button.
  • The text is DOM text in --ascii-font, so it stays sharp at any zoom and can be selected and copied.