Live demo
Everything below is the player itself, running here. Each demo was compiled during this build from the file under “Source” — the commands in the scenarios really ran, once, and castwright recorded what they printed.
Tip
Scenarios
A first demo, end to end
Write a demo file, validate it, build it to an SVG and to a cast. Real castwright output, recorded with exec: and --record.
Source: site/src/demos/first-demo.terminal.yaml
# Scenario: a first demo, end to end. Recorded, not written: the castwright
# commands were exec: steps, run once in a scratch project with
# `castwright build --allow-exec --record`, which replaced each with the command
# and exactly what it printed. The shown file is files/install.terminal.yaml.
version: 1
terminal:
title: ~/my-site
cols: 92
rows: 24
theme: catppuccin-mocha
steps:
- run: cat demos/install.terminal.yaml
- show: files/install.terminal.yaml
- wait: 2000
- run: castwright validate demos/install.terminal.yaml
- wait: 600
- run: castwright build demos/install.terminal.yaml --format svg
- output:
raw: |
dist/install.svg
- wait: 600
- run: castwright build demos/install.terminal.yaml
- output:
raw: |
dist/install.cast
- wait: 600
- run: du -h dist/*
- output:
raw: |
4.0K dist/install.cast
8.0K dist/install.svg
delay: 4
- wait: 2500$ cat demos/install.terminal.yaml
version: 1
terminal:
title: my-cli
cols: 72
rows: 10
theme: catppuccin-mocha
steps:
- run: npm install -g my-cli
- output: |
{green}✓{/} added 1 package in 2s
- run: my-cli init
- output: |
Created {bold}my-cli.config.json{/}
- wait: 1500
$ castwright validate demos/install.terminal.yaml
$ castwright build demos/install.terminal.yaml --format svg
dist/install.svg
$ castwright build demos/install.terminal.yaml
dist/install.cast
$ du -h dist/*
4.0K dist/install.cast
8.0K dist/install.svgAn error, and its fix
A typo in a demo file: validate points at the line and column, a one-line fix, and the build goes through.
Source: site/src/demos/error-fix.terminal.yaml
# Scenario: an error, and its fix. Recorded like first-demo: real commands,
# run once with `castwright build --allow-exec --record`.
version: 1
terminal:
title: ~/my-site
cols: 116
rows: 20
theme: catppuccin-mocha
steps:
- run: castwright validate demos/deploy.terminal.yaml
- output:
raw: |
demos/deploy.terminal.yaml:5:5: unknown key 'sped' in step 'run' — known keys: run, speed, jitter, pause, prompt
sped: 30
^
delay: 16
- wait: 2500
- run: perl -pi -e 's/sped:/speed:/' demos/deploy.terminal.yaml
- wait: 400
- run: castwright validate demos/deploy.terminal.yaml && echo "✓ valid"
- output:
raw: |
✓ valid
- wait: 800
- run: castwright build demos/deploy.terminal.yaml --format svg
- output:
raw: |
dist/deploy.svg
- wait: 2500$ castwright validate demos/deploy.terminal.yaml
demos/deploy.terminal.yaml:5:5: unknown key 'sped' in step 'run' — known keys: run, speed, jitter, pause, prompt
sped: 30
^
$ perl -pi -e 's/sped:/speed:/' demos/deploy.terminal.yaml
$ castwright validate demos/deploy.terminal.yaml && echo "✓ valid"
✓ valid
$ castwright build demos/deploy.terminal.yaml --format svg
dist/deploy.svgA VHS tape, built as is
examples/vhs.tape in unchanged VHS syntax. Its commands ran during this site's build; hidden setup included.
Source: examples/vhs.tape
# A VHS tape, built by castwright as is:
# castwright build examples/vhs.tape --format svg --allow-exec
Set FontSize 20
Set Width 900
Set Height 360
Set Theme "Catppuccin Mocha"
Set TypingSpeed 40ms
Hide
Type "cd snippets && clear" Enter
Show
Type "ls" Sleep 300ms Enter
Sleep 1s
Type "head -3 astro.config.ts" Sleep 300ms Enter
Sleep 2s> ls
astro.config.ts broken.terminal.yaml
> head -3 astro.config.ts
import castwright from '@casoon/astro-castwright';
import { defineConfig } from 'astro/config';
> Features
A file, highlighted
show: reads a file and highlights it with Shiki, at build time.
Source: examples/show.terminal.yaml
version: 1
terminal:
title: show
cols: 64
rows: 12
theme: catppuccin-mocha
steps:
- run: cat astro.config.ts
- show: snippets/astro.config.ts
- wait: 1500$ cat astro.config.ts
import castwright from '@casoon/astro-castwright';
import { defineConfig } from 'astro/config';
// Compiles every *.terminal.yaml at build time.
export default defineConfig({
integrations: [castwright()],
});A real command, recorded
exec: ran castwright once; --record kept exactly what it printed.
Source: examples/recorded.terminal.yaml
version: 1
terminal:
title: castwright validate
cols: 110
rows: 9
theme: catppuccin-mocha
steps:
# Recorded, not written: this was an exec: step, and
# `castwright build --allow-exec --record` ran it once and replaced it
# with the command and exactly what it printed.
- run: castwright validate broken.terminal.yaml
- output:
raw: |
broken.terminal.yaml:5:5: unknown key 'sped' in step 'run' — known keys: run, speed, jitter, pause, prompt
sped: 30
^
delay: 50
- wait: 1500$ castwright validate broken.terminal.yaml
broken.terminal.yaml:5:5: unknown key 'sped' in step 'run' — known keys: run, speed, jitter, pause, prompt
sped: 30
^Keys and seeded jitter
Tab completion, human-looking typing — the same bytes on every build.
Source: site/src/demos/keys.terminal.yaml
version: 1
terminal: { cols: 56, rows: 7 }
seed: 7
steps:
- type: npm ru
jitter: 0.4
- key: tab
- wait: 250
- type: "n build"
- key: enter
- output: |
{green}✓{/} built in 412ms
- wait: 1200npm ru n build ✓ built in 412ms
Output, line by line
delay: prints a block one line at a time.
Source: site/src/demos/output-delay.terminal.yaml
version: 1
terminal: { cols: 56, rows: 9 }
steps:
- run: npm test
- output: |
{green}✓{/} parser
{green}✓{/} compiler
{green}✓{/} player
{dim}3 passed{/}
delay: 400
- wait: 1200$ npm test ✓ parser ✓ compiler ✓ player 3 passed
Colour and style
Named colours follow the theme; #rrggbb is exact.
Source: site/src/demos/colours.terminal.yaml
version: 1
terminal: { cols: 56, rows: 9 }
steps:
- output: |
{red}red{/} {green}green{/} {yellow}yellow{/} {blue}blue{/}
{bright-magenta}bright-magenta{/} {cyan}cyan{/}
{bg-blue} on blue {/} {#f38ba8}#f38ba8{/}
{bold}bold{/} {dim}dim{/} {italic}italic{/} {underline}underline{/}
{green}nested {bold}bold green{/} still green{/}
- wait: 1500red green yellow blue bright-magenta cyan on blue #f38ba8 bold dim italic underline nested bold green still green
The same demo as an SVG
castwright build --format svg — one file, no script, plays inside a plain <img>, on GitHub too.
castwright build error-fix.terminal.yaml --format svg
<img src="error-fix.svg" alt="…">One cast, four themes
A cast stores colours as palette indices and carries its palette in the header, so the same compiled demo plays in any of the seven bundled themes.
default
$ pnpm add -D @casoon/castwright ✓ added 3 packages $ castwright build demo.terminal.yaml dist/demo.cast
dracula
$ pnpm add -D @casoon/castwright ✓ added 3 packages $ castwright build demo.terminal.yaml dist/demo.cast
solarized-dark
$ pnpm add -D @casoon/castwright ✓ added 3 packages $ castwright build demo.terminal.yaml dist/demo.cast
github-light
$ pnpm add -D @casoon/castwright ✓ added 3 packages $ castwright build demo.terminal.yaml dist/demo.cast
Without the chrome
For a hero section you often want the terminal and nothing else. The controls are still there — hover the demo, or tab to it — because a loop that never stops needs a way to stop it.
Bare, looping
<TerminalDemo demo={demo} autoplay loop chrome="none" controls="hover" />
$ pnpm add -D @casoon/castwright ✓ added 3 packages $ castwright build demo.terminal.yaml dist/demo.cast