Blog / / 5 min read
Our docs videos are code
Every video in the Lexington docs is rendered from a script file committed to the repo: real commands, the site's own palette and font, no screen recording. Here is the setup, and why the last docs change took a two-minute re-render instead of a re-shoot.
Documentation videos have a short shelf life. You record a flow, ship it, and three weeks later a command changes, a screen looks different, or the advice itself gets better. Now the video is wrong, and fixing it means setting up a recording session, getting a clean take, editing, exporting, and compressing. So most docs videos just stay wrong.
The videos in the Lexington docs don’t have that problem, because none of them are recordings. They’re scripts.
Terminal recordings as code
Every video is a .tape file rendered with VHS, a tool that types commands into a real terminal and captures the result. A tape reads like stage directions:
Set FontFamily "Geist Mono"
Set FontSize 26
Type "unzip -q primapersona-main.zip"
Enter
Wait@30s
Type "npm install --no-audit --no-fund"
Enter
Wait@120s
Type "npm run dev"
Enter
Wait+Screen@60s /localhost/
Sleep 5sThat’s not pseudocode. It’s the actual install video from the docs, trimmed. VHS types each command at a human speed, runs it for real, waits for real output, and renders the whole session to MP4.
The tapes live in the repository next to the site, and each one renders straight into the public folder the docs serve videos from. The video is an artifact of the script, the same way a build is an artifact of the source.
Nothing is mocked
The commands genuinely run. The install video really unzips a theme, really runs npm install, and really starts the dev server; the Wait+Screen@60s /localhost/ line means “hold until the dev server actually prints its URL.” If the theme were broken, the video would fail to render.
That turns the videos into a low-key integration test. A recording can show a flow that stopped working months ago. A tape can’t, because rendering it is running the flow.
Setup that isn’t part of the story stays off camera. VHS has Hide and Show directives, so environment prep, cache warming, and cleanup happen invisibly between frames. The viewer sees only the steps they’ll actually take.
They look like the site because they use the site’s tokens
A screen recording of my terminal would ship my prompt, my color scheme, and whatever was in my scrollback. The tapes instead declare their appearance, and the values come from the same design tokens the site uses:
Set Theme { "background": "#FAF9F8", "foreground": "#2B2B2B", "cursor": "#1062FE", ... }That’s the site palette from colors.css, and Geist Mono is the site’s code font. The videos sit in the docs like they were designed there, because they were.
There’s a practical bonus: terminal output compresses absurdly well. The install video, at full 1920×1080, is about 220 KB. A screen recording of the same flow would be twenty times that.
The payoff: a re-shoot is a re-render
This week I changed the installation advice. The docs used to demonstrate cloning the theme repository; the better guidance is to fork it or download the ZIP, so your copy is your own.
With recorded video, that’s a session: re-record, re-edit, re-export, re-upload. With a tape, it was editing a few lines in a text file and running one command:
vhs scripts/videos/install-a-theme.tapeTwo minutes later the docs had a new video showing the new flow, pixel-consistent with every other video on the site. The diff even goes through code review like everything else, because a video change is a code change.
If you want this for your own docs
A few things I learned rendering these for a whole docs section:
- Silence the noise. Set
CI=1so CLIs skip update checks and interactive prompts; unset any env vars that make tools print warnings. Anything your shell whispers ends up on camera. - Warm the caches first. Run the install once before rendering so the recorded one is short. Nobody needs to watch a cold
npm install. - Wait on output, not on time.
Wait+Screenon a pattern like/localhost/makes renders deterministic. Fixed sleeps either waste seconds or cut off early. - Free your ports. If the video starts a dev server, stop your own first, or the video ships a “port in use” warning forever.
- Write down the prep. Each tape starts with a comment block explaining how to prepare the environment. Six months later, that comment is the difference between a re-render and archaeology.
The whole setup is one binary and some text files. For terminal-heavy docs, I can’t see a reason to record a screen ever again.
I also packaged all of this as a free agent skill, so your AI coding tool can write good tapes for you. It covers everything above, plus pacing, interactive TUIs, and a pre-render checklist:
npx skills add michael-andreuzza/vhs-demo-videosThe skill is plain Markdown; read it on GitHub before you install it, like any skill.
/Michael Andreuzza