VHS — Terminal Recorder
VHS records terminal sessions from declarative .tape files.
Produces GIF, MP4, or WebM. No screen recording needed — deterministic and reproducible.
Install
bash
scoop install vhs # Windows brew install vhs # macOS
Requires ffmpeg (for video encoding). scoop install ffmpeg if missing.
Quick Start
bash
# Create example tape vhs new demo.tape # Record vhs demo.tape # Validate without running vhs validate demo.tape # Publish to vhs.charm.sh (get shareable URL) vhs publish demo.gif
Tape File Syntax
Output
tape
Output demo.gif # GIF (default, best for READMEs) Output demo.mp4 # MP4 video Output demo.webm # WebM video
Multiple Output lines = multiple formats from one tape.
Settings
tape
Set Shell "bash" # Shell to use Set FontSize 14 # Font size (default 22 — too large for most) Set FontFamily "JetBrains Mono" # Font family Set Width 1200 # Terminal width in pixels Set Height 600 # Terminal height in pixels Set Padding 15 # Padding around terminal Set TypingSpeed 50ms # Delay between keystrokes (default 50ms) Set Theme "Dracula" # Color theme (see Themes below) Set Framerate 30 # GIF framerate Set PlaybackSpeed 1.0 # Playback speed multiplier Set LoopOffset 80% # Where GIF loop restarts (% from end) Set WindowBar "Colorful" # Window bar: Rings, RingsRight, Colorful, ColorfulRight Set WindowBarSize 40 # Window bar height in pixels Set BorderRadius 8 # Terminal border radius Set MarginFill "#1a1a2e" # Background color outside terminal Set Margin 20 # Margin size (needs MarginFill)
Commands
tape
Type "echo hello" # Type characters Type@100ms "slow typing" # Type with custom speed Enter # Press Enter Enter 3 # Press Enter 3 times Sleep 2s # Wait 2 seconds Sleep 500ms # Wait 500 milliseconds # Special keys Backspace 5 # Delete 5 chars Tab # Tab completion Ctrl+C # Interrupt Ctrl+L # Clear screen Up # Arrow up (history) Down # Arrow down Left 3 # Move cursor left 3 Right 3 # Move cursor right 3 Escape # Escape key Space # Space key PageUp # Page up PageDown # Page down # Visibility Hide # Hide commands from output Show # Show commands again
Require
tape
Require git # Fail if git not in PATH Require node
Recommended Defaults
For README demos and documentation:
tape
Output demo.gif Set Shell "bash" Set FontSize 14 Set Width 1100 Set Height 600 Set Theme "Dracula" Set TypingSpeed 30ms Set Padding 15 Set WindowBar "Colorful" Set BorderRadius 8
Patterns
Simple command showcase
tape
Output demo.gif Set Shell "bash" Set FontSize 14 Set Width 1100 Set Height 600 Set Theme "Dracula" Set TypingSpeed 30ms Set Padding 15 Type "my-tool --help" Enter Sleep 3s Type "my-tool run --input data.json" Enter Sleep 5s
Complex commands (use a wrapper script)
VHS tape files don't support shell quoting well. For complex commands with quotes, pipes, or multi-line args, write a helper script:
bash
# demo-run.sh #!/bin/bash echo "Running analysis..." my-tool analyze --format json | jq '.results[] | .name'
tape
Type "bash demo-run.sh" Enter Sleep 10s
Hide setup, show the interesting part
tape
# Setup (hidden from recording) Hide Type "cd /tmp/demo-project" Enter Type "export DEMO_MODE=1" Enter Sleep 1s Show # Visible demo starts here Type "my-tool init" Enter Sleep 3s
Before/after comparison
tape
Type "# Before:" Enter Type "cat config.yaml" Enter Sleep 3s Type "# After running fix:" Enter Type "my-tool fix config.yaml" Enter Sleep 3s Type "cat config.yaml" Enter Sleep 3s
Recording live (interactive)
bash
# Record your terminal actions into a tape file vhs record > my-session.tape # Then edit the tape to clean up timing, add sleeps, etc. vhs my-session.tape
Themes
Popular themes for demos:
| Theme | Style |
|---|---|
Dracula | Dark purple — high contrast, popular |
Catppuccin Mocha | Dark warm — modern, easy on eyes |
Tokyo Night | Dark blue — clean |
Nord | Dark muted — professional |
Gruvbox Dark | Dark warm/retro |
Solarized Dark | Classic |
GitHub Dark | Familiar to devs |
One Dark | VS Code-like |
List all: vhs themes
Tips
- •FontSize 14 — default 22 is way too large for most demos
- •TypingSpeed 25-40ms — 50ms default feels slow; 25ms is snappy
- •Sleep after Enter — always add
Sleepafter commands to let output render - •Long commands — use wrapper scripts, VHS quoting is fragile
- •GIF size — keep under 5MB for GitHub READMEs; reduce Framerate, Height, or duration
- •Multiple outputs — one tape can produce
.gif+.mp4simultaneously - •Publish —
vhs publish demo.gifgives a shareable URL on vhs.charm.sh - •Validate first —
vhs validate demo.tapecatches syntax errors without recording
Gotchas
- •No shell expansion in Type —
Type "echo $HOME"types the literal string; variable expansion happens when bash executes it, not in the tape - •Quoting — avoid nested quotes in Type. Use wrapper scripts for complex commands
- •Windows paths — use forward slashes in Type strings (
C:/dev/...notC:\dev\...) - •Long recordings — GIFs get huge fast. Keep demos under 30 seconds. Use
Set PlaybackSpeed 2.0to compress - •Terminal size — if output wraps weird, increase Width or reduce FontSize