A number of our open source projects and products showcases features via short terminal demo videos.

People often ask us how we generate such beautiful demos 💅 so we thought we'd take a bit of time to explain the process.

The tooling

We use VHS, a small terminal recorder written in Go by the amazing charm.sh team. VHS takes a script file (a "tape") describing what to type and when, then produces an MP4 or GIF.

Think of it as a screencast you write with code. A tape looks like this:

Type "echo 'VHS is cool'"
Enter

Sleep 2s

You run it with vhs demo.tape and the result looks like this:

VHS demo recording (light theme) VHS demo recording (dark theme)

Try switching themes to see the difference:

VHS can handle typing speed, color schemes, windows styles, and much more. It's a lovely little tool!

Real world demos

Club Matto ships many projects and each requires many demos that we ship both in light and dark mode, which is kind of a standard nowadays (even GitHub READMEs support it!).

We also crafted a specific look and feel for such demos and this requires lots of custom configuration like fonts, default speeds, colors. Moreover, this looks and feel needs to be consistent across all demos.

Fortunately, VHS can source other tapes so each recording is assembled from three files at generation time:

  • config.tape: shared base settings (font, size, padding, typing speed).
  • config-{theme}.tape: the light/dark colour palette.
  • <demo>.tape: the actual demo.

This allows us to add new demos by focusing only on the content, it's a productive setup. In the first iterations, we had a bash script to glue everything together but, as it often happens, the script soon stopped scaling.

VHS generate tool

Vetrina is a monorepo and a core advantage of monorepos is that they allow you to build tooling around your workflow in a very productive manner. So when regenerating all our demos was taking too long and iterating over our demo setup became too painful, we rewrote the script in Go.

VHS generate does a few useful things:

  • Parallel generation — up to four VHS processes run concurrently, cutting total time significantly.
  • Lifecycle hooks — a requirements.sh per project can define setup, before_each, after_each, and cleanup functions. Needed when a demo requires a database or a freshly built binary.
  • Selective output — every demo produces an MP4 for web use; only demos listed in a gifs.txt manifesto also produce a GIF (which we use in readmes and preview links).
  • One-shot recordings — the --tape flag pipes a self-contained tape directly to VHS with no project directory needed. Useful for social media posts.

Running all demos for a project:

go run tools/vhs-generate/main.go fakedata

Running a specific demo in light mode only:

go run tools/vhs-generate/main.go -t light fakedata basic

If you'd like to use our generate tool, please reach out and we'll package it as a small, installable CLI.