↓ Skip to main content

Quick tip: easy terminal demo gifs with `vhs` 📼

·469 words·3 mins
Table of Contents

I build commandline tools pretty often, but I never liked making screenshots. Sometimes they’re blurry due to zooming, or I change my interface or output format, and now my screenshot is out of date.

If you struggle with this too, let me introduce vhs.

vhs (named for the VHS video cartridge format) turns a simple scripting language into animated gifs. Want to see how it works? Let’s rewind and start from the beginning!

Install vhs
#

vhs is available in many installer formats, including:

  • Brew: brew install vhs
  • Go: go install github.com/charmbracelet/vhs@latest
Important

You’ll need ttyd and ffmpeg, as vhs uses them to make the gifs.

Writing your first vhs tape
#

The vhs language is simple, and can be viewed with vhs manual. Here are the most vital bits:

  • Type "things go here" : sends keystrokes to the virtual terminal.
  • Enter : sends an enter key.
  • Sleep <time> : waits (giving your viewer time to read)
  • Hide / Show : allows you to Type things but not show them in the output
  • Arrow keys: Left Right Up Down.

With just this tiny subset, you can make pretty elaborate demonstrations of terminal tools and applications.

For a more complete example (that’s almost entirely just the above items), you can see the demo.tape for a2term.

Run the tape:
#

Not much to say here. just vhs demo.tape.

Once the tool is done, you should get a smooth gif like this:

a2term demo gif

Creating the tape file is a bit of upfront work. You can use an LLM to create them (agents do a pretty good job, IMO). But there’s also an easier way: vhs record.

Record mode will generate a tape file for you, based on your actions. Note that it will output the tapefile to stdout, so you may want to run vhs record > myfile.tape

Warning

vhs’ default shell is bash. so if you’re using bash, it may look like the vhs record command hasn’t done anything. I recommend specifying a the shell with --shell to ensure you dont forget you’re recording a tape file!

Once you exit the subshell vhs spawned, you can check out your new tape file and make any necessary changes.

If you really want these images to be automatic, you could create a Github Actions workflow to run the vhs files and submit the changes – be careful though, that might cause an infite loop of re-generation!

(consider an on-demand workflow that only triggers on workflow_dispatch, then you can run it with the push of a button!)

While writing this, I learned that vhs can also take screenshots! So If you want static screenshots, you can add Screenshot homepage.png to your tape file, and it will also output a still image, in addition to your animated gif.

Happy recording, and “be kind, rewind”! 🤣 🎬