# Retro computer

A vintage workstation in glyphs: a CRT on a desktop unit and a keyboard, its screen typing a live session in real characters.

> For the complete documentation index, see [llms.txt](/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](/.well-known/agent-skills/asciicn/SKILL.md).

> **This is an example, not the only option.** It is one component built on the asciicn engine. Install it when it is what you were asked for. For any other look, don't stretch its props to fit: write your own field on `AsciiShader` ([Write your own](/docs/engine/write-your-own.md)), or draw a CPU grid with `AsciiGrid`, and read this example's source for technique. Its full source is in [https://asciicn.dev/r/retro-computer.json](https://asciicn.dev/r/retro-computer.json), under `files[].content`.

## Installation [#installation]

```bash
npx shadcn@latest add https://asciicn.dev/r/retro-computer.json
```

## Usage [#usage]

```tsx
import { RetroComputer } from "@/components/asciicn/retro-computer";

const script = [
  { command: "DIR", output: ["README.TXT  GAME.EXE"] },
  { command: "RUN GAME.EXE", output: ["LOADING ..."] },
];

export function Hero() {
  return <RetroComputer script={script} className="h-[480px] w-full" />;
}
```

The computer is a small 3D model: a desktop unit with two drive bays, vents and a power light, a CRT whose housing tapers back from the bezel, and a keyboard with its keys laid out in rows. It is projected in perspective and rasterised at the charset's sample grid. Each face is flat-shaded from a fixed light, so the top, front and side of the case each get their own glyph density, and a one-sample gap traces every edge where two faces meet.

The glass shows a live session. The computer types each command in `script` after `prompt`, prints its output line by line, then moves on, looping forever. The characters are real glyphs placed where their spot on the tube projects, so the text leans with the monitor as it sways, with a slight bulge like curved glass. A key on the keyboard dips each time a character is typed.

It rests in a three-quarter view and sways a little. It does not react to hover. Press and drag to turn it; it coasts and stays where you leave it. With keyboard focus, the arrow keys turn it.

## Examples [#examples]

### Your own session [#your-own-session]

Pass `script`, `prompt` and `banner` to type anything. Lines longer than the screen is wide wrap onto the next row, so short lines read best. Here a green phosphor and a shell prompt.

```tsx title="examples/retro-computer-session.tsx"
import { RetroComputer } from "@/components/asciicn/retro-computer";

const SCRIPT = [
  {
    command: "npx shadcn add retro-computer",
    output: ["+ components/asciicn/retro-computer.tsx", "done."],
  },
  {
    command: "pnpm dev",
    output: ["ready on http://localhost:3000"],
  },
];

export default function RetroComputerSession() {
  return (
    <RetroComputer
      script={SCRIPT}
      banner={["ACME OS 2.1", ""]}
      prompt="$ "
      screen="p1"
      className="aspect-[4/3] w-full max-w-xl"
    />
  );
}
```

### Classic ASCII in your theme's ink [#classic-ascii-in-your-themes-ink]

The `standard` ramp draws each side of the case with its own glyph, so the faces read as `#`, `+` and `:`. `color="--ascii-ink"` paints the case in the theme's ink instead of beige, and the `ibm` phosphor gives the screen white text.

```tsx title="examples/retro-computer-classic.tsx"
import { RetroComputer } from "@/components/asciicn/retro-computer";

export default function RetroComputerClassic() {
  return (
    <RetroComputer
      charset="standard"
      screen="ibm"
      color="--ascii-ink"
      cell={12}
      fx={{ bloom: 0.35, vignette: 0.3 }}
      className="aspect-[4/3] w-full max-w-xl"
    />
  );
}
```

## Props [#props]

Every [ASCII image](/docs/images/ascii-image#props) look prop also applies to the case, with `charset` defaulting to `"braille"`, plus `fx` for a CRT finish. The text on the screen is always drawn in real characters, whatever the charset.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `script` | `{ command: string; output: string[] }[]` | `a tour of a disk` | The session the computer types, looping: each command after the prompt, then its output. |
| `prompt` | `string` | `"C:\\>"` | The prompt before each command. |
| `banner` | `string[]` | `a memory check` | Lines printed at power-on, above the session. |
| `screen` | `"p1" \| "p3" \| "ibm" \| "blueprint"` | `"p3"` | The screen's phosphor: green, amber, white or cyan. |
| `color` | `AsciiColor` | `"#d8cdb1"` | Case colour in truecolor, an aged beige by default. |
| `typing` | `number` | `0.06` | Seconds per typed character. |
| `charset` | `CharsetName` | `"braille"` | Which glyphs draw the case. |
| `colorMode` | `"mono" \| "truecolor" \| "ansi16" \| "duotone" \| "palette"` | `"truecolor"` | How glyphs are coloured. |
| `interactive` | `boolean` | `true` | Drag or use the arrow keys to turn it. |
| `cell` | `number` | `11` | Glyph cell height in CSS pixels. |
| `speed` | `number` | `1` | Multiplies the typing and the sway. |
| `animate` | `boolean` | `true` | false draws one still frame. |
| `handle` | `RefObject<AsciiHandle \| null>` |  | Filled with a handle for export. |

## Notes [#notes]

* It is announced as an image. The session on the screen is decoration, so screen readers don't read it; if the text matters, put it on the page as well, and pass `aria-label` to describe the picture.
* Under reduced motion it draws one still frame, partway through the session, with no sway. Dragging and the arrow keys still turn it.
* It draws at up to 30 fps on the CPU and pauses offscreen and in hidden tabs. The model has under 40 faces, so the cost is filling the samples they cover.
* The text grid is sized from the monitor's projected size, so a small box fits fewer characters per line and long lines wrap sooner. Lower `cell` to fit more.