Communitygithub.com

jdrurka/explainer-skill

Turns a concept (and optionally the user's own script) into a finished faceless "how X really works" explainer video - AI voiceover from Fish Audio, full-frame animated visuals built in Remotion code, top captions that build word by word, no music. Every animation event is keyed to a spoken word's timestamp. Use when the user says "make an explainer", "explainer video about <topic>", "how does <thing> work video", "animated explainer", "under the hood video", or hands over a script and wants visuals with no footage.

What is explainer-skill?

explainer-skill is a Claude Code agent skill that turns a concept (and optionally the user's own script) into a finished faceless "how X really works" explainer video - AI voiceover from Fish Audio, full-frame animated visuals built in Remotion code, top captions that build word by word, no music. Every animation event is keyed to a spoken word's timestamp. Use when the user says "make an explainer", "explainer video about <topic>", "how does <thing> work video", "animated explainer", "under the hood video", or hands over a script and wants visuals with no footage.

Works with~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/jdrurka/explainer-skill/tree/HEAD/.claude/skills/explainer

Ask in your favorite AI

Open a new chat with this agent skill pre-loaded.

Documentation

Explainer

A faceless explainer is a voiceover over one continuous, code-built animated world (a cut-through, a magnified mechanism, a hand holding an object), with captions at the top and no music. The output is a 1080×1920 mp4.

Read these before writing:

  • script-craft.md: how the script is shaped (hook, twist, imagine, mechanism, flip, CTA) and paced.
  • craft-rules.md: what makes the visuals feel alive and dimensional. A competent first pass breaks most of these.

The hard part is the visual metaphor for each beat. The second hardest is keeping every frame moving and lit with depth. Code is the easy part.

Modes

  • One-shot (default): go from concept to final video without stopping. Make the judgment calls yourself and report them at the end.
  • Review: if the user asks to review or approve, stop twice: after the script, and after the storyboard. Revise from their notes and continue.

Setup check (once)

ffmpeg on PATH, remotion/node_modules present (otherwise run npm install in remotion/), and FISH_API_KEY in .env (copy .env.example). With no key, build everything on voice --placeholder and tell the user that the final step is one voice re-run plus a render.

Layout

projects/<concept>/ (the concept is a slug, like how-fridges-work):

  • script.txt, storyboard.md
  • composition.tsx (layer stack), timeline.ts (TL), captions.ts, words.ts (generated), scenes/S01.tsx …
  • public/vo.wav, vo/ (raw take and alignment), out/ (renders, stills)

The core library is remotion/src/core (scenes import it as ../../../remotion/src/core):

  • makeTimeline → TL.at("phrase"), TL.end("phrase")
  • Captions, Drift, Bokeh, Vignette, handheld, Backdrop, Dust, Footnote
  • Camera (WorldSvg, camAt, toScreen), Label, Sparks, Snow / Rain
  • easings, ramp, keys, rand, fonts SANS / MONO

Tools: python3 bin/explainer.py … (run -h)

CommandDoes
new <c>Scaffolds the project
voice <c> [--voice-id ID] [--speed 1.0]Fish Audio take with word timestamps → words.ts, plus public/vo.wav at −14 LUFS. Prints the wpm
voice <c> --placeholder [--wpm 200]Silent audio and synthetic timings, with no API call
stills <c> <sec>…Frames at those seconds → one contact sheet in out/. Look at it
studio <c>Live preview in Remotion Studio (for the user)
render <c> [--blur]60 fps mp4 in out/. --blur renders at 240 fps and averages to 60 for motion blur (~4× slower)
qa <c>Liveness gate: frozen frames < 10%, no frozen run ≥ 0.3 s. Exits 1 on FAIL and names each frozen stretch

Workflow

  1. Script. Run new <c>.

    • If the user gave a script, use it word for word (fix only numerals and symbols into words).
    • Otherwise write script.txt from script-craft.md: everyday-object format by default (270–320 words), system format for products and networks. Run its checklist.
    • Review mode: stop for approval.
  2. Voice. Run voice <c>, then check the printed wpm (aim for 190–215; re-run with the suggested --speed if it's off).

    • The voice is --voice-id, else FISH_VOICE_ID, else Fish's default. A cloned voice's id works the same way.
    • The model is --model, else FISH_MODEL, else s2.1-pro.
    • Author against words.ts, not script.txt. The voice spells out numbers, and TL.at() and caption phrases must match the spoken words.
  3. Storyboard (storyboard.md). Fill the World section first, then one row per beat. To invent a beat's metaphor, ask what the viewer would see if they could:

    • Magnify: a cut-through or exploded view.
    • X-ray: inside the object.
    • Slow time: a wave travelling, a part switching.
    • Measure: a readout climbing or dipping.

    The "imagine" scenario becomes the excursion world, and every mechanism beat returns to the home diagram. Run the storyboard checks.

    • Review mode: stop for approval.
  4. Build. Write one scene file per storyboard shot in scenes/ and add each to composition.tsx.

    • Each scene is a pure function of t that returns null outside its window.
    • Timing: every event is keyed to TL.at("exact words"). Never write raw seconds.
    • Continuity: beats that share a diagram live in ONE scene with ONE camera path (A4).
    • Moves: each scene enters by moving, overlapping the previous scene's exit (A2).
    • Prefix SVG ids per scene.
  5. Iterate. Run stills at each shot's key words and look at them against craft rules A and B. Then run render and qa. Fix every FROZEN stretch in its own shot by giving it a carrier of motion (A1b). Write captions.ts phrases by hand: one highlighted (amber, pops when spoken) key noun per phrase.

  6. Deliver. The final render must pass qa (use --blur if the user wants maximum polish). Give the user:

    • the mp4 path
    • the script
    • a one-line-per-beat summary of the storyboard
    • any placeholder voice that still needs a real take

Red flags: stop and fix

ThoughtRule
"A new setting for this beat keeps it fresh"C1: one home diagram plus 1–2 excursion worlds. Count them
"Hold dead still on the payoff for suspense"A1c: stop the subject, keep the camera and ambient moving
"Add a music bed, grain or a drop on the payoff"D, B8: voice only, no grain; depth comes from lighting
"Fade it in" / "crossfade to the next scene"A2: enter, exit and transition by moving
"The global drift will keep it alive"A1b: each shot needs a mid-size mover at 10–60 px/s
"Cut to a closer camera for this beat" (same diagram)A4: one world, one camera; hand off keyframes
"Even lighting is fine, it's a diagram"B1: falloff into the dark, rim light, vignette
"Tint the whole thing when it activates"B4: propagate from the cause, with a front and flow
"A rectangle is fine for the object"B2: one anatomy pass; build what a pull-out will reveal
"Looks fine to me, skip qa"E: qa must PASS; eyes miss freezes

Related Skills