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.
Installation
brew install vhsVHS 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:
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
ShowRun it:
vhs glow-render.tapeBeyond 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-fontOutput 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.webmMP4 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.