castwrightv0.3.0

CASOON Open Source

Terminal demos you write, not record.

castwright compiles a small YAML file to asciicast v2 and plays it as a real terminal — real ANSI, real cursor movement, selectable text — with no headless browser anywhere in your build.

pnpm add -D @casoon/castwright
npm i -D @casoon/castwright
yarn add -D @casoon/castwright
MITasciicast v2xterm.jsWCAG 2.2 AA
examples/basic.terminal.yaml
$ npx casoon create my-app
✓ Creating project
✓ Installing dependencies
✓ Project ready
$ cd my-app && npm run dev
ready in 412ms

  ➜  Local:  http://localhost:4321/
unit tests
381
browser tests, desktop and mobile
22
axe violations at WCAG 2.2 AA
0
parser or compiler shipped to the browser
0 kB

What it does

  1. Authored, not performed

    No recording session to get right on the seventh take. Edit a line, rebuild, and the demo changes — the same way the rest of your documentation does.

  2. A real terminal, not a lookalike

    xterm.js interprets the bytes, so cursor movement, line rewrites and carriage returns behave as they would in a shell. Coloured spans in a <pre> cannot do that.

  3. Deterministic output

    The same input compiles to the same bytes on every machine. A generated .cast is a text file you commit and read in a diff, and typing jitter is seeded so it stays that way.

  4. One file, every output

    The same .cast plays in the page, exports to an animated SVG for a README — real text, no JavaScript — and to GIF or MP4 for everywhere else.

  5. Real files and real commands

    show: puts a file on screen, syntax-highlighted at build time. exec: runs a command for real, and --record writes its output back into the file so every later build replays the same bytes.

  6. Accessible by construction

    The element’s children are the terminal’s final text, generated at build time — real content before the script loads and if it never does. Reduced motion is honoured and there is always a pause control.

Generated at build time

All examples →
demo.terminal.yaml
version: 1

terminal:
  cols: 72
  rows: 12
  theme: catppuccin-mocha

steps:
  - run: pnpm add -D @casoon/castwright
  - output: |
      {green}✓{/} added 3 packages
  - wait: 500
  - run: castwright build demo.terminal.yaml
  - output: |
      {dim}dist/demo.cast{/}

This is the file that produced the terminal at the top of the page, compiled during this build. No screenshots, nothing kept in step by hand.

examples/basic.terminal.yaml

Quickstart

Three steps from install to a demo on the page. The walkthrough, the DSL reference and the integration guides are in the documentation.

  1. Register the Vite plugin, or the Astro integration that wraps it.
  2. Write a *.terminal.yaml file describing the session.
  3. Import it and hand it to <TerminalDemo>, or to the <castwright-demo> element directly.
src/pages/index.astro
---
import TerminalDemo from '@casoon/astro-castwright/TerminalDemo.astro';
import demo from '../demos/install.terminal.yaml';
---

<TerminalDemo demo={demo} autoplay loop />