⚙️ Node 22+ and FFmpeg
Two required binaries: Node.js version 22 or higher and FFmpeg available on the PATH. Without them, HyperFrames can't render a single frame.
HyperFrames uses Native ESM and APIs for fs/promises available starting with Node 18, but version 22 brings the --experimental-strip-types and the updated V8 that speeds up composition parsing. Older versions (16, 18) may work partially but cause warnings and unexpected behavior in build-index.mjs.
- ✓ FFmpeg in
C:\ffmpeg\bin\ffmpeg.exe - ✓ PATH configured in the system (non-user)
- ✓ Node 22+ verified with
node --version - ✓ Open a new terminal after changing PATH
- ✗ Use FFmpeg installed by
chocowithout checking PATH - ✗ Node 16 or 18 — causes errors with native ESM
- ✗ Test
ffmpegin the old terminal (PATH not updated) - ✗ ffmpeg.exe outside the subdirectory
bin
⌨️ ffmpeg -nostdin in git-bash
The quietest setup gotcha: running FFmpeg inside git-bash without -nostdin causes exit 0 without generating any files. No visible error — nothing is simply created.
⚠️ Critical gotcha—exits with code 0 without a file
In git-bash (MinTTY), FFmpeg tries to read stdin and silently blocks. The process exits with code 0 (success), but no MP4 is generated. It's the hardest bug to diagnose because everything seems to have worked.
The HyperFrames CLI (npx hyperframes render) passes -nostdin automatically in internal calls to FFmpeg. You only need to worry about this if you invoke FFmpeg directly in git-bash for manual post-processing, concatenation scripts, etc.
🌐 HyperFrames headless Chrome
HyperFrames comes with its own Chrome headless — it doesn’t depend on Chrome installed on the system. A single command downloads and links the exact version tested with the CLI.
Different Chrome versions render CSS and GSAP animations with subtle pixel differences. To make the output deterministic (same HTML → same MP4), HyperFrames locks to a specific Chromium version via Puppeteer, downloaded and managed internally. You don’t need to touch the system Chrome.
Reads the pinned version in HyperFrames’ package.json
The field puppeteer.chromiumRevision specifies exactly which Chromium build to use — no "latest".
Checks the local cache (~/.cache/puppeteer/)
If the build already exists, skip the download. The second project you create doesn't wait for anything — instant.
Downloads ~170MB from the Chromium CDN if needed
Only the first time or when the HyperFrames version is updated. A stable connection is recommended.
🔊 Kokoro TTS
100% local PT-BR narration, with no API key. Kokoro has its own Portuguese phonemizer, so espeak-ng isn't needed. On the first run, it downloads ~340MB of model files.
- ✓
pip install kokoro-onnx soundfile - ✓ Python 3.10+ on PATH
- ✓ First run: wait for ~340MB download
- ✓ Default voice:
pf_dorawith--speed 0.98
- ✗ espeak-ng — Kokoro doesn't need it and it causes a conflict
- ✗ Other TTS packages that depend on espeak
- ✗ Interrupt the model's first download
- ✗ Use
speed 1.0+— sounds mechanical in PT-BR
espeak-ng phonemizes Portuguese poorly — technical words sound robotic. Kokoro has its own PT-BR phonemizer trained specifically for the language.
The model (~340MB) is cached in ~/.cache/kokoro/. From the second invocation onward, generating a 10s clip takes less than 2 seconds.
🩺 npx hyperframes doctor
The diagnostic command checks the entire stack at once: Node, FFmpeg, Chrome, and Kokoro. If something is wrong, it tells you exactly what’s missing.
Especially in a new environment or after updating HyperFrames. The npx hyperframes render fails midway through the process if a dependency is missing — the doctor detects it beforehand.
Node.js — minimum version 18, recommended 22+
Reads process.version and compares it with the field engines from package.json.
FFmpeg — runs ffmpeg -version and parses the output
Checks whether the binary is accessible via PATH and shows the full path found.
Chrome — check Puppeteer cache
Check if the stuck build is at ~/.cache/puppeteer/. If not, suggest running browser ensure.
Kokoro — import the Python module and check
Runs python -c "import kokoro_onnx" e import soundfile. Minimum versions checked.
📦 Start a project
With the environment ready, the next step is to create the project structure. The template blank + --non-interactive generates everything without questions — ideal for scripts and CI.
O --example blank creates a minimal project with the correct folder structure but no prebuilt scenes — you start from scratch. It's the recommended entry point for learning the pipeline, since each file that appears was created intentionally.
init blank- ✓ Read the
design.mdto understand the palette - ✓ Run
node scripts/fetch-fonts.mjsbefore the render - ✓ Use
narration-template.shas the script basis - ✓ Run
doctoronce in the new project
- ✗ Render without running
fetch-fonts.mjs→ font not found - ✗ Ignore the
design.mdand invent a color palette - ✗ Skip the
npm installafter init - ✗ Use spaces in the project name (e.g.,
meu video)
Each project has a design.md with the main palette, typography, and visual style. For INEMA.CLUB videos, the default palette is: background #0D1321, amber accent #FACC15, white/gray text. Claude reads this file before writing any scene.
📋 Module 2.2 summary
What you learned in this module
- ✓ Node.js 22+ installed and verified with
node --version - ✓ FFmpeg in
C:\ffmpeg\binadded to the system PATH - ✓ Headless Chrome installed via
npx hyperframes browser ensure - ✓ Kokoro TTS installed (
pip install kokoro-onnx soundfile), without espeak-ng - ✓
npx hyperframes doctorreturning "All systems go" - ✓ First project created with
npx hyperframes init <nome> --example blank --non-interactive - ✓
fetch-fonts.mjsexecuted, fonts downloaded - ✓ Understood why
-nostdinis required in git-bash
narration-template.sh, generate the audio files with Kokoro (pf_dora --speed 0.98) and measure the durations with ffprobe to sync with the scenes.