{"id":13459314,"url":"https://github.com/charmbracelet/vhs","last_synced_at":"2025-05-12T05:16:08.026Z","repository":{"id":62158459,"uuid":"515619101","full_name":"charmbracelet/vhs","owner":"charmbracelet","description":"Your CLI home video recorder 📼","archived":false,"fork":false,"pushed_at":"2025-04-28T11:42:04.000Z","size":40241,"stargazers_count":16358,"open_issues_count":101,"forks_count":287,"subscribers_count":34,"default_branch":"main","last_synced_at":"2025-05-12T02:43:16.776Z","etag":null,"topics":["ascii","cli","command-line","gif","recording","terminal","vhs","video"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/charmbracelet.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-07-19T14:28:36.000Z","updated_at":"2025-05-12T01:52:45.000Z","dependencies_parsed_at":"2023-10-04T02:56:10.677Z","dependency_job_id":"4f3a31c7-e2d7-4683-aa54-ee687eba12da","html_url":"https://github.com/charmbracelet/vhs","commit_stats":{"total_commits":632,"total_committers":50,"mean_commits":12.64,"dds":"0.30221518987341767","last_synced_commit":"5a207ef92d81b671c9d0f30ddb245434cb49a2f8"},"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/charmbracelet%2Fvhs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/charmbracelet%2Fvhs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/charmbracelet%2Fvhs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/charmbracelet%2Fvhs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/charmbracelet","download_url":"https://codeload.github.com/charmbracelet/vhs/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253672675,"owners_count":21945479,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ascii","cli","command-line","gif","recording","terminal","vhs","video"],"created_at":"2024-07-31T09:01:15.420Z","updated_at":"2025-05-12T05:16:08.000Z","avatar_url":"https://github.com/charmbracelet.png","language":"Go","readme":"# VHS\n\n\u003cp\u003e\n  \u003cimg src=\"https://user-images.githubusercontent.com/42545625/198402537-12ca2f6c-0779-4eb8-a67c-8db9cb3df13c.png#gh-dark-mode-only\" width=\"500\" /\u003e\n  \u003cimg src=\"https://user-images.githubusercontent.com/42545625/198402542-a305f669-a05a-4d91-b18b-ca76e72b655a.png#gh-light-mode-only\" width=\"500\" /\u003e\n  \u003cbr\u003e\n  \u003ca href=\"https://github.com/charmbracelet/vhs/releases\"\u003e\u003cimg src=\"https://img.shields.io/github/release/charmbracelet/vhs.svg\" alt=\"Latest Release\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://pkg.go.dev/github.com/charmbracelet/vhs?tab=doc\"\u003e\u003cimg src=\"https://godoc.org/github.com/golang/gddo?status.svg\" alt=\"Go Docs\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/charmbracelet/vhs/actions\"\u003e\u003cimg src=\"https://github.com/charmbracelet/vhs/workflows/build/badge.svg\" alt=\"Build Status\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\nWrite terminal GIFs as code for integration testing and demoing your CLI tools.\n\n\u003cimg alt=\"Welcome to VHS\" src=\"https://stuff.charm.sh/vhs/examples/neofetch_3.gif\" width=\"600\" /\u003e\n\nThe above example was generated with VHS ([view source](./examples/neofetch/neofetch.tape)).\n\n## Tutorial\n\nTo get started, [install VHS](#installation) and create a new `.tape` file.\n\n```sh\nvhs new demo.tape\n```\n\nOpen the `.tape` file with your favorite `$EDITOR`.\n\n```sh\nvim demo.tape\n```\n\nTape files consist of a series of [commands](#vhs-command-reference). The commands are\ninstructions for VHS to perform on its virtual terminal. For a list of all\npossible commands see [the command reference](#vhs-command-reference).\n\n```elixir\n# Where should we write the GIF?\nOutput demo.gif\n\n# Set up a 1200x600 terminal with 46px font.\nSet FontSize 46\nSet Width 1200\nSet Height 600\n\n# Type a command in the terminal.\nType \"echo 'Welcome to VHS!'\"\n\n# Pause for dramatic effect...\nSleep 500ms\n\n# Run the command by pressing enter.\nEnter\n\n# Admire the output for a bit.\nSleep 5s\n```\n\nOnce you've finished, save the file and feed it into VHS.\n\n```sh\nvhs demo.tape\n```\n\nAll done! You should see a new file called `demo.gif` (or whatever you named\nthe `Output`) in the directory.\n\n\u003cpicture\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://stuff.charm.sh/vhs/examples/demo.gif\"\u003e\n  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://stuff.charm.sh/vhs/examples/demo.gif\"\u003e\n  \u003cimg width=\"600\" alt=\"A GIF produced by the VHS code above\" src=\"https://stuff.charm.sh/vhs/examples/demo.gif\"\u003e\n\u003c/picture\u003e\n\nFor more examples see the [`examples/`](https://github.com/charmbracelet/vhs/tree/main/examples) directory.\n\n## Installation\n\n\u003e [!NOTE]\n\u003e VHS requires [`ttyd`](https://github.com/tsl0922/ttyd) and [`ffmpeg`](https://ffmpeg.org) to be installed and available on your `PATH`.\n\nUse a package manager:\n\n```sh\n# macOS or Linux\nbrew install vhs\n\n# Arch Linux (btw)\npacman -S vhs\n\n# Nix\nnix-env -iA nixpkgs.vhs\n\n# Windows using scoop\nscoop install vhs\n```\n\nOr, use Docker to run VHS directly, dependencies included:\n\n```sh\ndocker run --rm -v $PWD:/vhs ghcr.io/charmbracelet/vhs \u003ccassette\u003e.tape\n```\n\nOr, download it:\n\n- [Packages][releases] are available in Debian and RPM formats\n- [Binaries][releases] are available for Linux, macOS, and Windows\n\nOr, just install it with `go`:\n\n```sh\ngo install github.com/charmbracelet/vhs@latest\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eWindows, Debian, Ubuntu, Fedora, RHEL, Void Instructions\u003c/summary\u003e\n\n- Debian / Ubuntu\n\n```sh\n# Debian/Ubuntu\nsudo mkdir -p /etc/apt/keyrings\ncurl -fsSL https://repo.charm.sh/apt/gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/charm.gpg\necho \"deb [signed-by=/etc/apt/keyrings/charm.gpg] https://repo.charm.sh/apt/ * *\" | sudo tee /etc/apt/sources.list.d/charm.list\n# Install ttyd from https://github.com/tsl0922/ttyd/releases\nsudo apt update \u0026\u0026 sudo apt install vhs ffmpeg\n```\n\n- Fedora / RHEL\n\n```sh\necho '[charm]\nname=Charm\nbaseurl=https://repo.charm.sh/yum/\nenabled=1\ngpgcheck=1\ngpgkey=https://repo.charm.sh/yum/gpg.key' | sudo tee /etc/yum.repos.d/charm.repo\n# Install ttyd from https://github.com/tsl0922/ttyd/releases\nsudo yum install vhs ffmpeg\n```\n\n- Void\n\n```sh\nsudo xbps-install vhs\n```\n\n- Windows\n\n```sh\nwinget install charmbracelet.vhs\n# or scoop\nscoop install vhs\n```\n\n\u003c/details\u003e\n\n[releases]: https://github.com/charmbracelet/vhs/releases\n\n## Record Tapes\n\nVHS has the ability to generate tape files from your terminal actions!\n\nTo record to a tape file, run:\n\n```bash\nvhs record \u003e cassette.tape\n```\n\nPerform any actions you want and then `exit` the terminal session to stop\nrecording. You may want to manually edit the generated `.tape` file to add\nsettings or modify actions. Then, you can generate the GIF:\n\n```bash\nvhs cassette.tape\n```\n\n## Publish Tapes\n\nVHS allows you to publish your GIFs to our servers for easy sharing with your\nfriends and colleagues. Specify which file you want to share, then use the\n`publish` sub-command to host it on `vhs.charm.sh`. The output will provide you\nwith links to share your GIF via browser, HTML, and Markdown.\n\n```bash\nvhs publish demo.gif\n```\n\n## The VHS Server\n\nVHS has an SSH server built in! When you self-host VHS you can access it as\nthough it were installed locally. VHS will have access to commands and\napplications on the host, so you don't need to install them on your machine.\n\nTo start the server run:\n\n```sh\nvhs serve\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eConfiguration Options\u003c/summary\u003e\n\n- `VHS_PORT`: The port to listen on (`1976`)\n- `VHS_HOST`: The host to listen on (`localhost`)\n- `VHS_GID`: The Group ID to run the server as (current user's GID)\n- `VHS_UID`: The User ID to run the server as (current user's UID)\n- `VHS_KEY_PATH`: The path to the SSH key to use (`.ssh/vhs_ed25519`)\n- `VHS_AUTHORIZED_KEYS_PATH`: The path to the authorized keys file (empty, publicly accessible)\n\n\u003c/details\u003e\n\nThen, simply access VHS from a different machine via `ssh`:\n\n```sh\nssh vhs.example.com \u003c demo.tape \u003e demo.gif\n```\n\n## VHS Command Reference\n\n\u003e [!NOTE]\n\u003e You can view all VHS documentation on the command line with `vhs manual`.\n\nThere are a few basic types of VHS commands:\n\n- [`Output \u003cpath\u003e`](#output): specify file output\n- [`Require \u003cprogram\u003e`](#require): specify required programs for tape file\n- [`Set \u003cSetting\u003e Value`](#settings): set recording settings\n- [`Type \"\u003ccharacters\u003e\"`](#type): emulate typing\n- [`Left`](#arrow-keys) [`Right`](#arrow-keys) [`Up`](#arrow-keys) [`Down`](#arrow-keys): arrow keys\n- [`Backspace`](#backspace) [`Enter`](#enter) [`Tab`](#tab) [`Space`](#space): special keys\n- [`Ctrl[+Alt][+Shift]+\u003cchar\u003e`](#ctrl): press control + key and/or modifier\n- [`Sleep \u003ctime\u003e`](#sleep): wait for a certain amount of time\n- [`Wait[+Screen][+Line] /regex/`](#wait): wait for specific conditions\n- [`Hide`](#hide): hide commands from output\n- [`Show`](#show): stop hiding commands from output\n- [`Screenshot`](#screenshot): screenshot the current frame\n- [`Copy/Paste`](#copy--paste): copy and paste text from clipboard.\n- [`Source`](#source): source commands from another tape\n- [`Env \u003cKey\u003e Value`](#env): set environment variables\n\n### Output\n\nThe `Output` command allows you to specify the location and file format\nof the render. You can specify more than one output in a tape file which\nwill render them to the respective locations.\n\n```elixir\nOutput out.gif\nOutput out.mp4\nOutput out.webm\nOutput frames/ # a directory of frames as a PNG sequence\n```\n\n### Require\n\nThe `Require` command allows you to specify dependencies for your tape file.\nThese are useful to fail early if a required program is missing from the\n`$PATH`, and it is certain that the VHS execution will not work as expected.\n\nRequire commands must be defined at the top of a tape file, before any non-\nsetting or non-output command.\n\n```elixir\n# A tape file that requires gum and glow to be in the $PATH\nRequire gum\nRequire glow\n```\n\n### Settings\n\nThe `Set` command allows you to change global aspects of the terminal, such as\nthe font settings, window dimensions, and GIF output location.\n\nSetting must be administered at the top of the tape file. Any setting (except\n`TypingSpeed`) applied after a non-setting or non-output command will be\nignored.\n\n#### Set Shell\n\nSet the shell with the `Set Shell \u003cshell\u003e` command\n\n```elixir\nSet Shell fish\n```\n\n#### Set Font Size\n\nSet the font size with the `Set FontSize \u003cnumber\u003e` command.\n\n```elixir\nSet FontSize 10\nSet FontSize 20\nSet FontSize 40\n```\n\n\u003cpicture\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://stuff.charm.sh/vhs/examples/font-size-10.gif\"\u003e\n  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://stuff.charm.sh/vhs/examples/font-size-10.gif\"\u003e\n  \u003cimg width=\"600\" alt=\"Example of setting the font size to 10 pixels\" src=\"https://stuff.charm.sh/vhs/examples/font-size-10.gif\"\u003e\n\u003c/picture\u003e\n\n\u003cpicture\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://stuff.charm.sh/vhs/examples/font-size-20.gif\"\u003e\n  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://stuff.charm.sh/vhs/examples/font-size-20.gif\"\u003e\n  \u003cimg width=\"600\" alt=\"Example of setting the font size to 20 pixels\" src=\"https://stuff.charm.sh/vhs/examples/font-size-20.gif\"\u003e\n\u003c/picture\u003e\n\n\u003cpicture\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://stuff.charm.sh/vhs/examples/font-size-40.gif\"\u003e\n  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://stuff.charm.sh/vhs/examples/font-size-40.gif\"\u003e\n  \u003cimg width=\"600\" alt=\"Example of setting the font size to 40 pixels\" src=\"https://stuff.charm.sh/vhs/examples/font-size-40.gif\"\u003e\n\u003c/picture\u003e\n\n#### Set Font Family\n\nSet the font family with the `Set FontFamily \"\u003cfont\u003e\"` command\n\n```elixir\nSet FontFamily \"Monoflow\"\n```\n\n\u003cpicture\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://stuff.charm.sh/vhs/examples/font-family.gif\"\u003e\n  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://stuff.charm.sh/vhs/examples/font-family.gif\"\u003e\n  \u003cimg width=\"600\" alt=\"Example of changing the font family to Monoflow\" src=\"https://stuff.charm.sh/vhs/examples/font-family.gif\"\u003e\n\u003c/picture\u003e\n\n#### Set Width\n\nSet the width of the terminal with the `Set Width` command.\n\n```elixir\nSet Width 300\n```\n\n\u003cpicture\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://stuff.charm.sh/vhs/examples/width.gif\"\u003e\n  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://stuff.charm.sh/vhs/examples/width.gif\"\u003e\n  \u003cimg width=\"300\" alt=\"Example of changing the width of the terminal\" src=\"https://stuff.charm.sh/vhs/examples/width.gif\"\u003e\n\u003c/picture\u003e\n\n#### Set Height\n\nSet the height of the terminal with the `Set Height` command.\n\n```elixir\nSet Height 1000\n```\n\n\u003cpicture\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://stuff.charm.sh/vhs/examples/height.gif\"\u003e\n  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://stuff.charm.sh/vhs/examples/height.gif\"\u003e\n  \u003cimg width=\"300\" alt=\"Example of changing the height of the terminal\" src=\"https://stuff.charm.sh/vhs/examples/height.gif\"\u003e\n\u003c/picture\u003e\n\n#### Set Letter Spacing\n\nSet the spacing between letters (tracking) with the `Set LetterSpacing`\nCommand.\n\n```elixir\nSet LetterSpacing 20\n```\n\n\u003cpicture\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://stuff.charm.sh/vhs/examples/letter-spacing.gif\"\u003e\n  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://stuff.charm.sh/vhs/examples/letter-spacing.gif\"\u003e\n  \u003cimg width=\"600\" alt=\"Example of changing the letter spacing to 20 pixels between characters\" src=\"https://stuff.charm.sh/vhs/examples/letter-spacing.gif\"\u003e\n\u003c/picture\u003e\n\n#### Set Line Height\n\nSet the spacing between lines with the `Set LineHeight` Command.\n\n```elixir\nSet LineHeight 1.8\n```\n\n\u003cpicture\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://stuff.charm.sh/vhs/examples/line-height.gif\"\u003e\n  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://stuff.charm.sh/vhs/examples/line-height.gif\"\u003e\n  \u003cimg width=\"600\" alt=\"Example of changing the line height to 1.8\" src=\"https://stuff.charm.sh/vhs/examples/line-height.gif\"\u003e\n\u003c/picture\u003e\n\n#### Set Typing Speed\n\n```elixir\nSet TypingSpeed 500ms # 500ms\nSet TypingSpeed 1s    # 1s\n```\n\nSet the typing speed of seconds per key press. For example, a typing speed of\n`0.1` would result in a `0.1s` (`100ms`) delay between each character being typed.\n\nThis setting can also be overwritten per command with the `@\u003ctime\u003e` syntax.\n\n```elixir\nSet TypingSpeed 0.1\nType \"100ms delay per character\"\nType@500ms \"500ms delay per character\"\n```\n\n\u003cpicture\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://stuff.charm.sh/vhs/examples/typing-speed.gif\"\u003e\n  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://stuff.charm.sh/vhs/examples/typing-speed.gif\"\u003e\n  \u003cimg width=\"600\" alt=\"Example of using the Type command in VHS\" src=\"https://stuff.charm.sh/vhs/examples/typing-speed.gif\"\u003e\n\u003c/picture\u003e\n\n#### Set Theme\n\nSet the theme of the terminal with the `Set Theme` command. The theme value\nshould be a JSON string with the base 16 colors and foreground + background.\n\n```elixir\nSet Theme { \"name\": \"Whimsy\", \"black\": \"#535178\", \"red\": \"#ef6487\", \"green\": \"#5eca89\", \"yellow\": \"#fdd877\", \"blue\": \"#65aef7\", \"magenta\": \"#aa7ff0\", \"cyan\": \"#43c1be\", \"white\": \"#ffffff\", \"brightBlack\": \"#535178\", \"brightRed\": \"#ef6487\", \"brightGreen\": \"#5eca89\", \"brightYellow\": \"#fdd877\", \"brightBlue\": \"#65aef7\", \"brightMagenta\": \"#aa7ff0\", \"brightCyan\": \"#43c1be\", \"brightWhite\": \"#ffffff\", \"background\": \"#29283b\", \"foreground\": \"#b3b0d6\", \"selection\": \"#3d3c58\", \"cursor\": \"#b3b0d6\" }\n```\n\n\u003cimg alt=\"Example of changing the theme to Whimsy\" src=\"https://stuff.charm.sh/vhs/examples/theme.gif\" width=\"600\" /\u003e\n\nYou can also set themes by name:\n\n```elixir\nSet Theme \"Catppuccin Frappe\"\n```\n\nSee the full list by running `vhs themes`, or in [THEMES.md](./THEMES.md).\n\n#### Set Padding\n\nSet the padding (in pixels) of the terminal frame with the `Set Padding`\ncommand.\n\n```elixir\nSet Padding 0\n```\n\n\u003cpicture\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://stuff.charm.sh/vhs/examples/padding.gif\"\u003e\n  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://stuff.charm.sh/vhs/examples/padding.gif\"\u003e\n  \u003cimg width=\"600\" alt=\"Example of setting the padding\" src=\"https://stuff.charm.sh/vhs/examples/padding.gif\"\u003e\n\u003c/picture\u003e\n\n#### Set Margin\n\nSet the margin (in pixels) of the video with the `Set Margin` command.\n\n```elixir\nSet Margin 60\nSet MarginFill \"#6B50FF\"\n```\n\n\u003cpicture\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://vhs.charm.sh/vhs-1miKMtNHenh7O4sv76TMwG.gif\"\u003e\n  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://vhs.charm.sh/vhs-1miKMtNHenh7O4sv76TMwG.gif\"\u003e\n  \u003cimg width=\"600\" alt=\"Example of setting the margin\" src=\"https://vhs.charm.sh/vhs-1miKMtNHenh7O4sv76TMwG.gif\"\u003e\n\u003c/picture\u003e\n\n#### Set Window Bar\n\nSet the type of window bar (Colorful, ColorfulRight, Rings, RingsRight) on the terminal window with the `Set WindowBar` command.\n\n```elixir\nSet WindowBar Colorful\n```\n\n\u003cpicture\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://vhs.charm.sh/vhs-4VgviCu38DbaGtbRzhtOUI.gif\"\u003e\n  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://vhs.charm.sh/vhs-4VgviCu38DbaGtbRzhtOUI.gif\"\u003e\n  \u003cimg width=\"600\" alt=\"Example of setting the margin\" src=\"https://vhs.charm.sh/vhs-4VgviCu38DbaGtbRzhtOUI.gif\"\u003e\n\u003c/picture\u003e\n\n#### Set Border Radius\n\nSet the border radius (in pixels) of the terminal window with the `Set BorderRadius` command.\n\n```elixir\n# You'll likely want to add a Margin + MarginFill if you use BorderRadius.\nSet Margin 20\nSet MarginFill \"#674EFF\"\nSet BorderRadius 10\n```\n\n\u003cpicture\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://vhs.charm.sh/vhs-4nYoy6IsUKmleJANG7N1BH.gif\"\u003e\n  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://vhs.charm.sh/vhs-4nYoy6IsUKmleJANG7N1BH.gif\"\u003e\n  \u003cimg width=\"400\" alt=\"Example of setting the margin\" src=\"https://vhs.charm.sh/vhs-4nYoy6IsUKmleJANG7N1BH.gif\"\u003e\n\u003c/picture\u003e\n\n#### Set Framerate\n\nSet the rate at which VHS captures frames with the `Set Framerate` command.\n\n```elixir\nSet Framerate 60\n```\n\n#### Set Playback Speed\n\nSet the playback speed of the final render.\n\n```elixir\nSet PlaybackSpeed 0.5 # Make output 2 times slower\nSet PlaybackSpeed 1.0 # Keep output at normal speed (default)\nSet PlaybackSpeed 2.0 # Make output 2 times faster\n```\n\n#### Set Loop Offset\n\nSet the offset for when the GIF loop should begin. This allows you to make the\nfirst frame of the GIF (generally used for previews) more interesting.\n\n```elixir\nSet LoopOffset 5 # Start the GIF at the 5th frame\nSet LoopOffset 50% # Start the GIF halfway through\n```\n\n#### Set Cursor Blink\n\nSet whether the cursor should blink. Enabled by default.\n\n```elixir\nSet CursorBlink false\n```\n\n\u003cpicture\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://vhs.charm.sh/vhs-3rMCb80VEkaDdTOJMCrxKy.gif\"\u003e\n  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://vhs.charm.sh/vhs-3rMCb80VEkaDdTOJMCrxKy.gif\"\u003e\n  \u003cimg width=\"600\" alt=\"Example of setting the cursor blink.\" src=\"https://vhs.charm.sh/vhs-3rMCb80VEkaDdTOJMCrxKy.gif\"\u003e\n\u003c/picture\u003e\n\n### Type\n\nUse `Type` to emulate key presses. That is, you can use `Type` to script typing\nin a terminal. Type is handy for both entering commands and interacting with\nprompts and TUIs in the terminal. The command takes a string argument of the\ncharacters to type.\n\nYou can set the standard typing speed with [`Set TypingSpeed`](#set-typing-speed)\nand override it in places with a `@time` argument.\n\n```elixir\n# Type something\nType \"Whatever you want\"\n\n# Type something really slowly!\nType@500ms \"Slow down there, partner.\"\n```\n\nEscape single and double quotes with backticks.\n\n```elixir\nType `VAR=\"Escaped\"`\n```\n\n\u003cpicture\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://stuff.charm.sh/vhs/examples/type.gif\"\u003e\n  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://stuff.charm.sh/vhs/examples/type.gif\"\u003e\n  \u003cimg width=\"600\" alt=\"Example of using the Type command in VHS\" src=\"https://stuff.charm.sh/vhs/examples/type.gif\"\u003e\n\u003c/picture\u003e\n\n### Keys\n\nKey commands take an optional `@time` and optional repeat `count` for repeating\nthe key press every interval of `\u003ctime\u003e`.\n\n```\nKey[@\u003ctime\u003e] [count]\n```\n\n#### Backspace\n\nPress the backspace key with the `Backspace` command.\n\n```elixir\nBackspace 18\n```\n\n\u003cpicture\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://stuff.charm.sh/vhs/examples/backspace.gif\"\u003e\n  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://stuff.charm.sh/vhs/examples/backspace.gif\"\u003e\n  \u003cimg width=\"600\" alt=\"Example of pressing the Backspace key 18 times\" src=\"https://stuff.charm.sh/vhs/examples/backspace.gif\"\u003e\n\u003c/picture\u003e\n\n#### Ctrl\n\nYou can access the control modifier and send control sequences with the `Ctrl`\ncommand.\n\n```elixir\nCtrl+R\n```\n\n\u003cpicture\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://stuff.charm.sh/vhs/examples/ctrl.gif\"\u003e\n  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://stuff.charm.sh/vhs/examples/ctrl.gif\"\u003e\n  \u003cimg width=\"600\" alt=\"Example of pressing the Ctrl+R key to reverse search\" src=\"https://stuff.charm.sh/vhs/examples/ctrl.gif\"\u003e\n\u003c/picture\u003e\n\n#### Enter\n\nPress the enter key with the `Enter` command.\n\n```elixir\nEnter 2\n```\n\n\u003cpicture\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://stuff.charm.sh/vhs/examples/enter.gif\"\u003e\n  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://stuff.charm.sh/vhs/examples/enter.gif\"\u003e\n  \u003cimg width=\"600\" alt=\"Example of pressing the Enter key twice\" src=\"https://stuff.charm.sh/vhs/examples/enter.gif\"\u003e\n\u003c/picture\u003e\n\n#### Arrow Keys\n\nPress any of the arrow keys with the `Up`, `Down`, `Left`, `Right` commands.\n\n```elixir\nUp 2\nDown 2\nLeft\nRight\nLeft\nRight\nType \"B\"\nType \"A\"\n```\n\n\u003cpicture\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://stuff.charm.sh/vhs/examples/arrow.gif\"\u003e\n  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://stuff.charm.sh/vhs/examples/arrow.gif\"\u003e\n  \u003cimg width=\"600\" alt=\"Example of pressing the arrow keys to navigate text\" src=\"https://stuff.charm.sh/vhs/examples/arrow.gif\"\u003e\n\u003c/picture\u003e\n\n#### Tab\n\nEnter a tab with the `Tab` command.\n\n```elixir\nTab@500ms 2\n```\n\n\u003cpicture\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://stuff.charm.sh/vhs/examples/tab.gif\"\u003e\n  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://stuff.charm.sh/vhs/examples/tab.gif\"\u003e\n  \u003cimg width=\"600\" alt=\"Example of pressing the tab key twice for autocomplete\" src=\"https://stuff.charm.sh/vhs/examples/tab.gif\"\u003e\n\u003c/picture\u003e\n\n#### Space\n\nPress the space bar with the `Space` command.\n\n```elixir\nSpace 10\n```\n\n\u003cpicture\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://stuff.charm.sh/vhs/examples/space.gif\"\u003e\n  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://stuff.charm.sh/vhs/examples/space.gif\"\u003e\n  \u003cimg width=\"600\" alt=\"Example of pressing the space key\" src=\"https://stuff.charm.sh/vhs/examples/space.gif\"\u003e\n\u003c/picture\u003e\n\n#### Page Up / Down\n\nPress the Page Up / Down keys with the `PageUp` or `PageDown` commands.\n\n```elixir\nPageUp 3\nPageDown 5\n```\n\n### Wait\n\nThe `Wait` command allows you to wait for something to appear on the screen.\nThis is useful when you need to wait on something to complete, even if you don't\nknow how long it'll take, while including it in the recording like a spinner or\nloading state.\nThe command takes a regular expression as an argument, and optionally allows to\nset the duration to wait and if you want to check the whole screen or just the\nlast line (the scope).\n\n```elixir\nWait\nWait            /World/\nWait+Screen     /World/\nWait+Line       /World/\nWait@10ms       /World/\nWait+Line@10ms  /World/\n```\n\nThe default regular expression is `/\u003e$/`, the wait timeout is `15s`, and the\ndefault scope is `Line`.\n\n### Sleep\n\nThe `Sleep` command allows you to continue capturing frames without interacting\nwith the terminal. This is useful when you need to wait on something to\ncomplete while including it in the recording like a spinner or loading state.\nThe command takes a number argument in seconds.\n\n```elixir\nSleep 0.5   # 500ms\nSleep 2     # 2s\nSleep 100ms # 100ms\nSleep 1s    # 1s\n```\n\n### Hide\n\nThe `Hide` command instructs VHS to stop capturing frames. It's useful to pause\na recording to perform hidden commands.\n\n```elixir\nHide\n```\n\nThis command is helpful for performing any setup and cleanup required to record\na GIF, such as building the latest version of a binary and removing the binary\nonce the demo is recorded.\n\n```elixir\nOutput example.gif\n\n# Setup\nHide\nType \"go build -o example . \u0026\u0026 clear\"\nEnter\nShow\n\n# Recording...\nType 'Running ./example'\n...\nEnter\n\n# Cleanup\nHide\nType 'rm example'\nEnter\n```\n\n### Show\n\nThe `Show` command instructs VHS to begin capturing frames, again. It's useful\nafter a `Hide` command to resume frame recording for the output.\n\n```elixir\nHide\nType \"You won't see this being typed.\"\nShow\nType \"You will see this being typed.\"\n```\n\n\u003cpicture\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://stuff.charm.sh/vhs/examples/hide.gif\"\u003e\n  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://stuff.charm.sh/vhs/examples/hide.gif\"\u003e\n  \u003cimg width=\"600\" alt=\"Example of typing something while hidden\" src=\"https://stuff.charm.sh/vhs/examples/hide.gif\"\u003e\n\u003c/picture\u003e\n\n### Screenshot\n\nThe `Screenshot` command captures the current frame (png format).\n\n```elixir\n# At any point...\nScreenshot examples/screenshot.png\n```\n\n### Copy / Paste\n\nThe `Copy` and `Paste` copy and paste the string from clipboard.\n\n```elixir\nCopy \"https://github.com/charmbracelet\"\nType \"open \"\nSleep 500ms\nPaste\n```\n\n### Env\n\n`Env` command sets the environment variable via key-value pair.\n\n```elixir\nEnv HELLO \"WORLD\"\n\nType \"echo $HELLO\"\nEnter\nSleep 1s\n```\n\n### Source\n\nThe `source` command allows you to execute commands from another tape.\n\n```elixir\nSource config.tape\n```\n\n---\n\n## Continuous Integration\n\nYou can hook up VHS to your CI pipeline to keep your GIFs up-to-date with\nthe official VHS GitHub Action:\n\n\u003e [⚙️ charmbracelet/vhs-action](https://github.com/charmbracelet/vhs-action)\n\nVHS can also be used for integration testing. Use the `.txt` or `.ascii` output\nto generate golden files. Store these files in a git repository to ensure there\nare no diffs between runs of the tape file.\n\n```elixir\nOutput golden.ascii\n```\n\n## Syntax Highlighting\n\nThere’s a tree-sitter grammar for `.tape` files available for editors that\nsupport syntax highlighting with tree-sitter:\n\n\u003e [🌳 charmbracelet/tree-sitter-vhs](https://github.com/charmbracelet/tree-sitter-vhs)\n\nIt works great with Neovim, Emacs, and so on!\n\n## Feedback\n\nWe’d love to hear your thoughts on this project. Feel free to drop us a note!\n\n- [Twitter](https://twitter.com/charmcli)\n- [The Fediverse](https://mastodon.social/@charmcli)\n- [Discord](https://charm.sh/chat)\n\n## License\n\n[MIT](https://github.com/charmbracelet/vhs/raw/main/LICENSE)\n\n---\n\nPart of [Charm](https://charm.sh).\n\n\u003ca href=\"https://charm.sh/\"\u003e\n  \u003cimg\n    alt=\"The Charm logo\"\n    width=\"400\"\n    src=\"https://stuff.charm.sh/charm-badge.jpg\"\n  /\u003e\n\u003c/a\u003e\n\nCharm热爱开源 • Charm loves open source\n","funding_links":[],"categories":["Go","开源类库","Command Line Utilities","Multimedia","cli","HarmonyOS","其他","Tools for LMS Content Creation","Creating GIFs","\u003ca name=\"screen-recorder\"\u003e\u003c/a\u003eScreen recorder","Command line - Linux","\u003ca name=\"Go\"\u003e\u003c/a\u003eGo","Productivity \u0026 Recording"],"sub_categories":["终端工具","Tools","Video","Windows Manager","网络服务_其他","Learning resources"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcharmbracelet%2Fvhs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcharmbracelet%2Fvhs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcharmbracelet%2Fvhs/lists"}