explainroo
Local renderer for narrated explainer videos
TLDR
SYNOPSIS
explainroo command [project] [arguments] [options]explainroo --help | -hexplainroo version | --version
DESCRIPTION
explainroo turns a project directory into a narrated MP4 on the local machine. `script.md` is the words the voice says. `scenes.js` draws the pictures in JavaScript, and a drawing can appear on a particular word. `video.json` sets the look, size, voice, and pace. Kokoro reads the script, a timestamped Whisper model marks when each word is spoken, Chrome draws the frames, and ffmpeg muxes picture, voice, music, and sound effects into `out/video.mp4`.Drawings can use hand-drawn lines, more than 1,800 Lucide icons, charts, code, terminal windows, your own screenshots, and optional AI illustrations. The tool also builds product-demo scenes: reconstructed app screens with a pointer that clicks and types. It does not shoot or import filmed footage.Most commands take the project directory as the first argument and use the current directory when it is omitted. `still` and `image` treat the first argument as a project only when that path contains `video.json`. --json prints machine-readable output on stdout; logs go to stderr. --quiet suppresses logs.The repository is written so a coding agent can author `script.md` and `scenes.js` by following `AGENTS.md`. The same commands work by hand. Inside a clone, `npm link` puts `explainroo` on `PATH`. Without a link, run `node bin/explainroo.js` from the repository.
PARAMETERS
--json
Machine-readable output on stdout. Logs stay on stderr.--quiet
Suppress log lines.--help, -h
Print the command summary.--version
Print the version and exit.
CONFIGURATION
A project is configured in `video.json`. Unknown or out-of-range values stop the command with an error. Useful keys:title
Title shown in the preview. Defaults from the script.theme
Look: `paper` (default), `clean`, `chalk`, `blueprint`, or `midnight`.size
`16:9` (default), a ratio (`9:16`, `1:1`, `4:5`), a platform name (`youtube`, `shorts`, `tiktok`, `reels`, `vertical`, `instagram`, `linkedin`, `square`), or `WIDTHxHEIGHT`.voice
Voice id (default `af_heart`). `explainroo voices` lists them.speed
How fast the voice speaks, from 0.6 to 1.6 (default 0.9).pace
Scales voice, pauses, and animation together, from 0.7 to 1.6 (default 1).fps
24, 25, 30 (default), 50, or 60.music
`true` (default) uses the look's music style. A style name (`warm`, `upbeat`, `calm`, `tech`, `playful`), an object `{ "style": "calm", "volume": 0.35 }`, or `false`.sfx
Sound effects: `true` (default), `"minimal"`, or `false`.captions
`true`, `false`, or `"auto"` (default). `"auto"` captions tall and square videos and leaves wide videos without captions.transition
`"auto"` (default), `fade`, `slide`, `wipe`, `zoom`, `brush`, or `cut`.watermark
Corner text, default `explainroo.com`. `false` turns it off.loudness
Target loudness of the finished video in LUFS (default -14).One scene can override timing in its `script.md` heading, for example `## outro {hold=2 transition=cut}` with `hold`, `lead`, `min`, or `transition`.
COMMANDS
init dir [--theme name] [--size size] [--pace N] [--voice id] [--title text]
Create a project: `video.json`, a starter `script.md` and `scenes.js`, an `assets/` directory, and a `.gitignore`. Refuses if `video.json` already exists. Defaults: theme `paper`, size `16:9`, voice `af_heart`, title from the directory name.voice [project] [--force]
Generate narration and word timings. Prints each scene's duration and how much of the speech check matched. Only changed scenes are redone unless --force is set.preview [project] [--port N]
Serve a live preview (default port 4400) and reload narration when `video.json` or `script.md` changes. Stop with Ctrl+C.still [project] [time ...] [--scale N]
Write PNG stills. A time is `12.5`, a scene id, `scene@2.4`, `scene@start`, or `scene@end`. With no times, saves the end of every scene. --scale defaults to 1.sheet [project] [--scene id] [--every seconds] [--cols N]
Write a contact sheet of the whole video, or of one scene.check [project] [--step seconds]
Look for layout, timing, and pronunciation problems. --step is the sample interval (default 0.25). Exits 1 when any finding is an error.render [project] [--draft] [--from s] [--to s] [--workers N] [--scale N] [--out file]
Write `out/video.mp4`. --draft writes a half-size `out/draft.mp4`. --from and --to are seconds. --workers is how many Chrome pages draw at once. --out sets the file.verify [project] [--file path]
Check the rendered file for duration, size, loudness, true peak, black frames, silence, and whether the narration is understandable. --file checks another file. Exits 1 on an error-level finding.image [project] name prompt [--model best|cheap] [--aspect ratio] [--ref a,b] [--style text] [--no-style]
Make one AI illustration through OpenRouter and save `assets/<name>.png`. Needs OPENROUTER_API_KEY.images [project]
List generated images and what they cost.voices
List the 28 English voices (American and British).say text [--voice id] [--speed N] [--out file]
Speak a short line to a WAV file. Default voice `af_heart`, speed 1, output `<voice>.wav`.themes
List the looks (`paper`, `clean`, `chalk`, `blueprint`, `midnight`) and the music styles.formats
List platform sizes (YouTube, Shorts, TikTok, Reels, Instagram, LinkedIn, and square) and the safe content area of each.icons [word ...]
Search the built-in icons by name and tag. With no words, prints how many icons are shipped.doctor [--fetch]
Check Node.js (20.11 or newer), ffmpeg, and Chrome or Chromium. Reports whether the Kokoro and Whisper models are cached. --fetch downloads them (about 400 MB the first time). Exits 1 when Node, ffmpeg, or Chrome is missing; missing models alone do not fail the command.help, version
Print usage or the version from `package.json`. --help / -h and --version do the same. An unknown command exits 2.
ENVIRONMENT
OPENROUTER_API_KEY
Key for the image command. Also read from a `.env` file in the explainroo checkout or the project.EXPLAINROO_CHROME
Path to Chrome or Chromium when auto-detection fails.EXPLAINROO_FFMPEG, EXPLAINROO_FFPROBE
Paths to ffmpeg and ffprobe.EXPLAINROO_CACHE
Where speech models are stored. Default `~/.cache/explainroo`.EXPLAINROO_OFFLINE
Set to `1` to refuse model downloads.EXPLAINROO_TTS_DTYPE
Voice-model precision. `fp32` is the default. `q8` is a smaller download and runs slower.EXPLAINROO_DEBUG
Set to `1` to print a full stack trace on errors.
CAVEATS
Install from the Git repository (Node.js 20.11 or newer, ffmpeg, and Chrome or Chromium). The public npm registry has no `explainroo` package:
HISTORY
explainroo is an MIT-licensed Node.js tool by Vincent Schmalbach. The GitHub repository was created on 25 September 2026. Speech is Kokoro (Apache-2.0), word timing is Whisper through Transformers.js, drawings use Rough.js and Lucide, Playwright drives Chrome, and ffmpeg writes the MP4. Fonts are under the SIL Open Font License.
