Vhs
Your CLI home video recorder 📼
Install / Use
/learn @charmbracelet/VhsREADME
VHS
<p> <img src="https://user-images.githubusercontent.com/42545625/198402537-12ca2f6c-0779-4eb8-a67c-8db9cb3df13c.png#gh-dark-mode-only" width="500" /> <img src="https://user-images.githubusercontent.com/42545625/198402542-a305f669-a05a-4d91-b18b-ca76e72b655a.png#gh-light-mode-only" width="500" /> <br> <a href="https://github.com/charmbracelet/vhs/releases"><img src="https://img.shields.io/github/release/charmbracelet/vhs.svg" alt="Latest Release"></a> <a href="https://pkg.go.dev/github.com/charmbracelet/vhs?tab=doc"><img src="https://godoc.org/github.com/golang/gddo?status.svg" alt="Go Docs"></a> <a href="https://github.com/charmbracelet/vhs/actions"><img src="https://github.com/charmbracelet/vhs/workflows/build/badge.svg" alt="Build Status"></a> </p>Write terminal GIFs as code for integration testing and demoing your CLI tools.
<img alt="Welcome to VHS" src="https://stuff.charm.sh/vhs/examples/neofetch_3.gif" width="600" />The above example was generated with VHS (view source).
Tutorial
To get started, install VHS and create a new .tape file.
vhs new demo.tape
Open the .tape file with your favorite $EDITOR.
vim demo.tape
Tape files consist of a series of commands. The commands are instructions for VHS to perform on its virtual terminal. For a list of all possible commands see the command reference.
# Where should we write the GIF?
Output demo.gif
# Set up a 1200x600 terminal with 46px font.
Set FontSize 46
Set Width 1200
Set Height 600
# Type a command in the terminal.
Type "echo 'Welcome to VHS!'"
# Pause for dramatic effect...
Sleep 500ms
# Run the command by pressing enter.
Enter
# Admire the output for a bit.
Sleep 5s
Once you've finished, save the file and feed it into VHS.
vhs demo.tape
All done! You should see a new file called demo.gif (or whatever you named
the Output) in the directory.
For more examples see the examples/ directory.
Installation
[!NOTE] VHS requires
ttydandffmpegto be installed and available on yourPATH.
Use a package manager:
# macOS or Linux
brew install vhs
# Arch Linux (btw)
pacman -S vhs
# Nix
nix-env -iA nixpkgs.vhs
# Windows using scoop
scoop install vhs
Or, use Docker to run VHS directly, dependencies included:
docker run --rm -v $PWD:/vhs ghcr.io/charmbracelet/vhs <cassette>.tape
Or, download it:
- Packages are available in Debian and RPM formats
- Binaries are available for Linux, macOS, and Windows
Or, just install it with go:
go install github.com/charmbracelet/vhs@latest
<details>
<summary>Windows, Debian, Ubuntu, Fedora, RHEL, Void Instructions</summary>
- Debian / Ubuntu
# Debian/Ubuntu
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://repo.charm.sh/apt/gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/charm.gpg
echo "deb [signed-by=/etc/apt/keyrings/charm.gpg] https://repo.charm.sh/apt/ * *" | sudo tee /etc/apt/sources.list.d/charm.list
# Install ttyd from https://github.com/tsl0922/ttyd/releases
sudo apt update && sudo apt install vhs ffmpeg
- Fedora / RHEL
echo '[charm]
name=Charm
baseurl=https://repo.charm.sh/yum/
enabled=1
gpgcheck=1
gpgkey=https://repo.charm.sh/yum/gpg.key' | sudo tee /etc/yum.repos.d/charm.repo
# Install ttyd from https://github.com/tsl0922/ttyd/releases
sudo yum install vhs ffmpeg
- Void
sudo xbps-install vhs
- Windows
winget install charmbracelet.vhs
# or scoop
scoop install vhs
</details>
Record Tapes
VHS has the ability to generate tape files from your terminal actions!
To record to a tape file, run:
vhs record > cassette.tape
Perform any actions you want and then exit the terminal session to stop
recording. You may want to manually edit the generated .tape file to add
settings or modify actions. Then, you can generate the GIF:
vhs cassette.tape
Publish Tapes
VHS allows you to publish your GIFs to our servers for easy sharing with your
friends and colleagues. Specify which file you want to share, then use the
publish sub-command to host it on vhs.charm.sh. The output will provide you
with links to share your GIF via browser, HTML, and Markdown.
vhs publish demo.gif
The VHS Server
VHS has an SSH server built in! When you self-host VHS you can access it as though it were installed locally. VHS will have access to commands and applications on the host, so you don't need to install them on your machine.
To start the server run:
vhs serve
<details>
<summary>Configuration Options</summary>
VHS_PORT: The port to listen on (1976)VHS_HOST: The host to listen on (localhost)VHS_GID: The Group ID to run the server as (current user's GID)VHS_UID: The User ID to run the server as (current user's UID)VHS_KEY_PATH: The path to the SSH key to use (.ssh/vhs_ed25519)VHS_AUTHORIZED_KEYS_PATH: The path to the authorized keys file (empty, publicly accessible)
Then, simply access VHS from a different machine via ssh:
ssh vhs.example.com < demo.tape > demo.gif
VHS Command Reference
[!NOTE] You can view all VHS documentation on the command line with
vhs manual.
There are a few basic types of VHS commands:
Output <path>: specify file outputRequire <program>: specify required programs for tape fileSet <Setting> Value: set recording settingsType "<characters>": emulate typingLeftRightUpDown: arrow keysBackspaceEnterTabSpace: special keysScrollUpScrollDown: scroll terminal viewportCtrl[+Alt][+Shift]+<char>: press control + key and/or modifierSleep <time>: wait for a certain amount of timeWait[+Screen][+Line] /regex/: wait for specific conditionsHide: hide commands from outputShow: stop hiding commands from outputScreenshot: screenshot the current frameCopy/Paste: copy and paste text from clipboard.Source: source commands from another tapeEnv <Key> Value: set environment variables
Output
The Output command allows you to specify the location and file format
of the render. You can specify more than one output in a tape file which
will render them to the respective locations.
Output out.gif
Output out.mp4
Output out.webm
Output frames/ # a directory of frames as a PNG sequence
Require
The Require command allows you to specify dependencies for your tape file.
These are useful to fail early if a required program is missing from the
$PATH, and it is certain that the VHS execution will not work as expected.
Require commands must be defined at the top of a tape file, before any non- setting or non-output command.
# A tape file that requires gum and glow to be in the $PATH
Require gum
Require glow
Settings
The Set command allows you to change global aspects of the terminal, such as
the font settings, window dimensions, and GIF output location.
Setting must be administered at the top of the tape file. Any setting (except
TypingSpeed) applied after a non-setting or non-output command will be
ignored.
Set Shell
Set the shell with the Set Shell <shell> command
Set Shell fish
Set Font Size
Set the font size with the Set FontSize <number> command.
Set FontSize 10
Set FontSize 20
Set FontSize 40
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://stuff.charm.sh/vhs/examples/font-size-10.gif">
<source media="(prefers-color-scheme: light)" srcset="https://stuff.charm.sh/vhs/examples/font-size-10.gif">
<img width="600" alt="Example of setting the font size to 10 pixels" src="https://stuff.charm.sh/vhs/examples/font-size-10.gif">
</picture>
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://stuff.charm.sh/vhs/examples/font-size-20.gif">
<source media="(prefers-color-scheme: light)" srcset="https://stuff.charm.sh/vhs/examples/font-size-20.gif">
<img width="600" alt="Example of setting the font size to 20 pixels" src="https://stuff.charm.sh/vhs/examples/font-size-20.gif">
</picture>
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://stuff.charm.sh/vhs/examples/font-size-40.gif">
<source media="(prefers-color-scheme: light)" srcset="https://stuff.charm.sh/vhs/examples/font-size-40.gif">
<img width="600" alt="Example of setting the font size to 40 pixels" src="https://stuff.charm.sh/vhs/examples/font-size-40.gif">
</picture>
Set Font Family
Set the font family with the Set FontFamily "<font>" command
Set FontFamily "Monoflow"
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://stuff.charm.sh/vhs/examples/font-family.gif">
<source media="(prefers-color-scheme: light)" srcset="https://stuff.charm.sh/vhs/examples/font-family.gif">
<img width="600" alt="Example of changing the font family to Monoflow" src="https://stuff.charm.sh/vhs/examples/font-family.gif">
</picture>
Set Width
Set the widt
