Narrated, captioned terminal demos — from a tiny script.
asciinema and VHS
record a silent terminal. Great for a GIF — useless the moment you want to
explain what's happening. termreel adds the missing half: a spoken voiceover
and burned-in captions, synced to each command, rendered to an .mp4 you can
drop in a README, a Show HN, or a launch tweet.
asciinema / VHS → silent terminal clip
termreel → the same clip, narrated + captioned, as an mp4
You write a few lines. termreel records the terminal, speaks your narration, burns the captions, and hands you a finished video.
termreel init greeting # writes greeting.reel — edit it
termreel build greeting.reel # → greeting.mp4 (narrated + captioned)A .reel script is just a command and what to say over it, one beat at a time:
name: greeting
title: Saying hello
intro: Here's a thirty-second tour.
run: echo "hello, world"
say: First, a friendly greeting.
caption: echo writes to standard output
run: ls -la
say: Then we list the directory.
outro: That's the whole idea.
outroSay: Narrated terminal demos, from a tiny script.
That's it. Every run: is one beat; say: is spoken, caption: is shown on
screen (it defaults to whatever you say). Run termreel build greeting.reel and
you get a finished greeting.mp4.
A silent screencast makes the viewer guess. Narration + captions is what turns a recording into a demo — and nothing in the terminal-recording world does it for you. termreel makes the narrated, captioned cut the default, not a video-editing chore.
- Tiny input. A command + a sentence per beat. No timeline editor, no DAW.
- Synced by construction. Each beat is its own segment, so the right sentence is spoken and captioned over the right command — never drifting.
- Stateful demos stay honest.
cd,export, files you create — termreel replays earlier commands off-camera so later beats run with real state, while the camera only shows the current command on a clean screen. - Headless. No screen, no GUI — renders on a CI box or a server.
Prerequisites
| To… | You need |
|---|---|
author a .reel — init, compile, build --dry-run |
Bun ≥ 1.1 (bundled into the Homebrew build — nothing else) |
render the mp4 — termreel build |
Bun plus the render stack: the auto-demo toolkit (AUTODEMO_HOME), a GEMINI_API_KEY, and vhs + ffmpeg |
Homebrew — a self-contained binary, no Bun needed at runtime:
brew install deemwar-products/oss/termreelnpm or Bun — the CLI runs on Bun, so Bun must be installed:
npm install -g @deemwar-products/termreel # needs Bun on your machine
# …or run from source:
git clone https://github.com/deemwar-products/termreel && cd termreel
bun link # puts `termreel` on your PATHtermreel --help
init,compile, andbuild --dry-runwork standalone — they need only Bun, no API key, nothing external. They author and validate your.reel.Rendering an mp4 is the heavy part.
termreel build(without--dry-run) shells out to the deemwar auto-demo toolkit and will fail without all of:
- the auto-demo toolkit on disk — set
AUTODEMO_HOME=/path/to/auto-demo(or pass--produce <path>). It is not bundled or on npm.- a
GEMINI_API_KEY— for the voiceover (Gemini TTS).vhsandffmpegon yourPATH.So you can try the authoring flow with zero setup; you only need the render stack when you actually want the video.
export AUTODEMO_HOME=/path/to/auto-demo # required for `build` — or pass --produce <path>
export GEMINI_API_KEY=... # required for `build` — the voiceover| command | what it does |
|---|---|
termreel init [name] |
scaffold a starter <name>.reel |
termreel compile <file> |
compile to the storyboard JSON (--out to a file) |
termreel build <file> |
render the narrated, captioned .mp4 |
termreel build options:
| flag | meaning |
|---|---|
-o, --out <file> |
where to write the mp4 (default ./<name>.mp4) |
--dry-run |
validate + print the render plan, don't render |
--plain |
skip the house style (no brand theme / default voice) |
--produce <path> |
path to the auto-demo produce.ts |
--workdir <dir> |
render scratch dir (default ./artifacts/<name>) |
A .reel file is line-based: key: value, with run: opening each beat.
Document keys (anywhere): name (required), title, subtitle, intro,
outro, outroSubtitle, outroSay, voice, theme, fontSize, typingSpeed,
width, height, shell, replay, setup (repeatable — hidden per-beat setup
like cd/export).
Beat keys (after a run:): say, caption, hold (seconds to hold; default
is estimated from the narration length).
Long say:/caption: values can continue on indented following lines.
Treat a .reel from someone else like a shell script — read it before you
build. A .reel runs its own run: commands in a real terminal, and any
setup: lines run hidden (off-camera, before each beat) by design. termreel
never invents commands — it only types what the file's author wrote — but that
means building an untrusted .reel runs their commands on your machine, just
like piping a stranger's script into your shell. Skim it first.
MIT licensed.
termreel is built by Deemwar. We build small, sharp
tools and ship production AI systems for teams that move fast.
Need a polished terminal demo, an internal tool, or an AI feature built right?