|
| 1 | +--- |
| 2 | +description: Writing and editing VHS `.tape` files for terminal demo GIFs |
| 3 | +--- |
| 4 | + |
| 5 | +# VHS Tape Files |
| 6 | + |
| 7 | +[VHS](https://github.com/charmbracelet/vhs) records terminal sessions into GIFs/MP4s/WebMs from `.tape` scripts. Run with `vhs demo.tape`. |
| 8 | + |
| 9 | +## Critical Syntax Rules |
| 10 | + |
| 11 | +### Type command and inline directives |
| 12 | + |
| 13 | +`Type`, `Sleep`, `Enter` are **separate directives on the same line**, delimited by the closing `"` of the `Type` string. The most common bug is forgetting to close the `Type` string, which causes `Sleep`/`Enter` to be typed literally into the terminal. |
| 14 | + |
| 15 | +``` |
| 16 | +# ✅ CORRECT — closing " before Sleep |
| 17 | +Type "echo hello" Sleep 300ms Enter |
| 18 | +
|
| 19 | +# ❌ WRONG — Sleep and Enter are typed as literal text |
| 20 | +Type "echo hello Sleep 300ms Enter |
| 21 | +``` |
| 22 | + |
| 23 | +### Type with @speed override |
| 24 | + |
| 25 | +Override typing speed per-command with `@<time>` immediately after `Type` (no space): |
| 26 | + |
| 27 | +``` |
| 28 | +Type@80ms '{"pageSize": 2}' Sleep 100ms |
| 29 | +``` |
| 30 | + |
| 31 | +### Quoting |
| 32 | + |
| 33 | +- Double quotes `"..."` are the standard Type delimiter |
| 34 | +- Single quotes `'...'` also work and are useful when the typed content contains double quotes (e.g. JSON) |
| 35 | +- Escape quotes inside strings with backticks: `` Type `VAR="value"` `` |
| 36 | +- When building shell commands with nested quotes, split across multiple `Type` lines: |
| 37 | + |
| 38 | +``` |
| 39 | +Type "gws drive files list --params '" Sleep 100ms |
| 40 | +Type@80ms '{"pageSize": 2, "fields": "nextPageToken,files(id)"}' Sleep 100ms |
| 41 | +Type "' --page-all" Sleep 300ms Enter |
| 42 | +``` |
| 43 | + |
| 44 | +> **Pitfall**: Every `Type` line that is followed by `Sleep` or `Enter` on the same line MUST close its string first. Audit each line to ensure the quote is closed before any directive. |
| 45 | +
|
| 46 | +## Settings (top of file only) |
| 47 | + |
| 48 | +Settings must appear before any non-setting command (except `Output`). `TypingSpeed` is the only setting that can be changed mid-tape. |
| 49 | + |
| 50 | +``` |
| 51 | +Output demo.gif |
| 52 | +
|
| 53 | +Set Shell "bash" |
| 54 | +Set FontSize 14 |
| 55 | +Set Width 1200 |
| 56 | +Set Height 1200 |
| 57 | +Set Theme "Catppuccin Mocha" |
| 58 | +Set WindowBar Colorful |
| 59 | +Set WindowBarSize 40 |
| 60 | +Set TypingSpeed 40ms |
| 61 | +Set Padding 20 |
| 62 | +``` |
| 63 | + |
| 64 | +## Common Commands |
| 65 | + |
| 66 | +| Command | Example | Notes | |
| 67 | +|---|---|---| |
| 68 | +| `Output` | `Output demo.gif` | `.gif`, `.mp4`, `.webm` | |
| 69 | +| `Type` | `Type "ls -la"` | Type characters | |
| 70 | +| `Type@<time>` | `Type@80ms "slow"` | Override typing speed | |
| 71 | +| `Sleep` | `Sleep 2s`, `Sleep 300ms` | Pause recording | |
| 72 | +| `Enter` | `Enter` | Press enter | |
| 73 | +| `Hide` / `Show` | `Hide` ... `Show` | Hide setup commands | |
| 74 | +| `Ctrl+<key>` | `Ctrl+C` | Key combos | |
| 75 | +| `Tab`, `Space`, `Backspace` | `Tab 2` | Optional repeat count | |
| 76 | +| `Up`, `Down`, `Left`, `Right` | `Up 3` | Arrow keys | |
| 77 | +| `Wait` | `Wait /pattern/` | Wait for regex on screen | |
| 78 | +| `Screenshot` | `Screenshot out.png` | Capture frame | |
| 79 | +| `Env` | `Env FOO "bar"` | Set env var | |
| 80 | +| `Source` | `Source other.tape` | Include another tape | |
| 81 | +| `Require` | `Require jq` | Assert program exists | |
| 82 | + |
| 83 | +## Hide/Show for Setup |
| 84 | + |
| 85 | +Use `Hide`/`Show` to run setup commands (e.g. setting `$PATH`, clearing screen) without recording them: |
| 86 | + |
| 87 | +``` |
| 88 | +Hide |
| 89 | +Type "export PATH=$PWD/target/release:$PATH" Enter |
| 90 | +Type "clear" Enter |
| 91 | +Sleep 2s |
| 92 | +Show |
| 93 | +``` |
| 94 | + |
| 95 | +## Checklist When Editing Tape Files |
| 96 | + |
| 97 | +1. **Every `Type` string must be closed** before `Sleep`/`Enter` on the same line |
| 98 | +2. **Multi-line Type sequences** that build a single shell command: ensure the final line closes its string and includes `Enter` |
| 99 | +3. **Sleep durations** after commands should be long enough for the command to finish (network calls may need 8s+) |
| 100 | +4. **Settings go at the top** — only `TypingSpeed` can appear later |
| 101 | +5. **Test locally** with `vhs <file>.tape` before committing |
0 commit comments