Scripted Recordings with VHS

VHS records terminal sessions from a script. Instead of screen recording and trimming, you write a .tape file that describes what to type, and VHS renders it into a GIF, MP4, or WebM with consistent timing and clean output.

Figure 1. VHS recording of glow rendering a markdown file

Installation

brew install vhs

VHS depends on ttyd and ffmpeg, both installed automatically by Homebrew.

Writing a Tape

Here’s the tape that produced Figure 1. It configures the terminal look (font, theme, window), hides shell setup from the viewer, then creates a markdown file and renders it with glow:

glow-render.tape
Output glow-render.mp4

Require glow

Set Shell "fish"
Set FontFamily "JetBrainsMono Nerd Font Mono"
Set FontSize 40
Set LineHeight 1.0
Set Width 2400
Set Height 1256
Set Theme "Catppuccin Mocha"
Set WindowBar Colorful
Set WindowBarSize 85
Set Padding 20
Set Margin 30
Set MarginFill "#f3f5f7"
Set BorderRadius 8
Set CursorBlink false
Set Framerate 30

Hide
Type "set fish_autosuggestion_enabled 0 && clear"
Enter
Sleep 500ms
Show

Sleep 500ms
Set TypingSpeed 35ms

Type 'echo "# VHS'
Enter
Sleep 150ms
Enter
Sleep 100ms
Type "`brew install vhs`"
Enter
Sleep 100ms
Enter
Sleep 100ms
Type "Write a **.tape** script. Run **vhs demo.tape**."
Enter
Sleep 150ms
Enter
Sleep 100ms
Type "> No screen recording. No trimming. Just code."
Enter
Sleep 200ms
Type '" > notes.md'
Sleep 300ms
Enter

Sleep 1s

Ctrl+L
Sleep 500ms
Set TypingSpeed 40ms
Type "glow notes.md"
Sleep 500ms
Enter
Sleep 3s

Hide
Type "rm notes.md"
Enter
Sleep 300ms
Show
Show all 66 lines

Run it:

vhs glow-render.tape

Beyond what’s shown here, VHS supports Ctrl+C, arrow keys, and Wait (blocks until expected output appears). Set LoopOffset 60% starts the GIF loop partway through so the viewer sees the result first.

Font Gotcha

VHS renders in headless Chromium, not your terminal emulator. It can only use system-installed fonts. If the font isn’t found, it falls back to a default monospace and produces broken letter-spacing with wide gaps between characters.

The fix: install the font system-wide. For JetBrains Mono Nerd Font:

brew install --cask font-jetbrains-mono-nerd-font

Output Formats

VHS renders GIF, MP4, and WebM. Add multiple Output lines to generate all three in one run:

Output demo.gif
Output demo.mp4
Output demo.webm

MP4 and WebM support full color and compress well. For this recording, MP4 was 114 KB, WebM 113 KB, and GIF 194 KB, with the gap growing for longer or more colorful recordings. GIF is limited to 256 colors per frame, so rich themes like Catppuccin or Dracula show grainy artifacts.

GIF is the most portable format since it works as a plain image anywhere, but it’s heavier. MP4 and WebM are smaller and sharper, with autoplay support via the <video> tag. Use MP4 or WebM for blog posts and GIF for GitHub READMEs where a click to play is unavoidable.

Also available via RSS, Telegram, or X (@rdiachenko)
Questions or ideas? Email me