Premium 9:16 Reel OS for Remotion. Five cinematic style families.Twenty-two production-tested presets. Audio-locked motion. IG-safe by default. Buy once, install in 60 seconds, scaffold a reel with one slash command, iterate in Claude Code, render to MP4.
npx @devinilabs/reelstack init # one-time setup, license check
# in Claude Code:
/reelstack-glass --preset=graphify --name=MyReel
cd MyReel && npm run dev # opens Remotion Studio
14 chapters. Start with the prompt template — it's the artifact you paste into Claude Code to ship a reel on the first try. Then mental model · 22-preset catalog · 13 slash commands · 14 lint rules · audio-locking pipeline · 6 recipes · cheat sheet. Use the chapter rail (left) or scroll.
02 · Prompt template
Paste this. Ship a reel.
Two paths. The simplest is to type a family slash command and let Claude walk you through every choice. The most precise is the structured brief below — drop your script, fill five fields, and paste. Both work — pick by mood.
Easiest path
Just type the slash command — Claude asks the rest
No brief required. Use this when you're exploring or don't have a script ready yet.
Type any family slash command (e.g. /reelstack-glass) and Claude walks you through:
Picks a preset. Claude prints a menu of every preset in the family with one-line use-cases (e.g. "Long-form skill drop with technical breakdown") and the recommended default. You reply with a number or preset key. Forbidden auto-defaults silently — only one preset there today.
Asks for a reel name. Short, no spaces (e.g. ClaudeWatch).
Asks for the voiceover path. Point at a .wav in public/audio/, or skip if you'll record later.
Scaffolds the reel and surfaces the family palette + signature primitives + reference reel — so iteration starts the moment Studio opens.
The structured briefs below are for buyers who want to encode their full intent in one paste — useful when you already have an audio file, a brand identity, and a hook ready.
The five anchors every brief must answer
01
Script
Drop the full voiceover narration. Claude extracts the hook, CTA, and product name from it — no need to repeat them as separate fields.
02
Family + preset
Type the slash command to set the family (e.g. /reelstack-glass). Claude presents the preset menu — reply with a number or key, or let it recommend the default.
03
Voiceover path
Without it, motion drifts 6+ seconds on a 90-second voiceover. Always pass an absolute path to a .wav file inside public/audio/.
04
Workflow list
Spell out the slash commands in order. Prevents Claude from skipping /reelstack-beats — the most-skipped step.
05
Acceptance criteria
Define “done” upfront: lint clean, critique threshold, render targets. Without it Claude will ship early.
The brief
Standard brief
Recommended default. Most reels start here.
# ReelStack brief
# Replace every <Name> below with your reel name (PascalCase, no spaces — e.g. ClaudeWatch, LaunchVideo).
Script:
<paste full voiceover script here>
Reel: <Name>
Voiceover: public/audio/<Name>.wav
Platforms: ig
Logo: /reelstack-icons logos:github-icon (or skip)
Screenshots: /reelstack-capture https://justdrop.dev --scroll (or skip)
Clips: (optional — drop MP4s into public/reel-asset/)
- demo.mp4 at BEATS.demo ← "you just type slash claude watch"
- result.mp4 at BEATS.result ← "30-minute video, in under two minutes"
Workflow (run in order):
1. /reelstack-glass --name=<Name> --vo=public/audio/<Name>.wav
2. Pick a preset — if the family has multiple, Claude prints the menu; reply with a number or key
3. /reelstack-beats public/audio/<Name>.wav ← paste BEATS at top of src/<Name>.tsx
4. /reelstack-capture <urls if any>
5. /reelstack-icons <brands if any>
6. /reelstack-lint src/<Name>.tsx ← fix every error (warnings flow through)
7. /reelstack-critique src/<Name>.tsx ← apply every "Quick" fix
Acceptance:
- /reelstack-lint passes with zero errors (warnings reviewed)
- /reelstack-critique scores ≥ 8 across all 5 dimensions
- BEATS const sourced from /reelstack-beats output, not eyeballed
Worked example
ClaudeWatchReel — filled-in
The brief populated with concrete values for a real Devini Labs production reel.
The script below is the canonical ClaudeWatchReel narration. The BEAT keys BEATS.demo and BEATS.result are real keys in the claudewatch preset's BEATS const, so Claude can wrap each clip in the correct <Sequence> without guessing.
# ReelStack brief — ClaudeWatch
Script:
This custom Claude skill literally watches video frame by frame.
Not just the transcript — the actual visuals.
You just type slash claude watch, paste the URL, hit enter.
A 30-minute video, broken down and rewritten, in under two minutes.
Comment AI to get this custom created Claude skill.
Reel: ClaudeWatch
Voiceover: public/audio/claudewatch.wav
Platforms: ig
Logo: /reelstack-icons logos:anthropic-icon logos:youtube-icon logos:obsidian
Clips: (drop MP4s into public/reel-asset/)
- claude-watch.mp4 at BEATS.demo ← "you just type slash claude watch, paste the URL, hit enter"
- claude-watch-result.mp4 at BEATS.result ← "30-minute video, broken down and rewritten, in under two minutes"
Workflow (run in order):
1. /reelstack-glass --name=ClaudeWatch --vo=public/audio/claudewatch.wav
2. Pick a preset — Claude prints the menu; reply with a number or key (e.g. claudewatch)
3. /reelstack-beats public/audio/claudewatch.wav ← paste BEATS at top of src/ClaudeWatch.tsx
4. /reelstack-icons logos:anthropic-icon logos:youtube-icon logos:obsidian
5. /reelstack-lint src/ClaudeWatch.tsx
6. /reelstack-critique src/ClaudeWatch.tsx
Acceptance:
- /reelstack-lint passes with zero errors (warnings reviewed)
- /reelstack-critique scores ≥ 8 across all 5 dimensions
- BEATS const sourced from /reelstack-beats output (not eyeballed)
- claude-watch.mp4 plays from BEATS.demo and ends at BEATS.result with no overlap
Anti-patterns — these waste an iteration
Don't write
Reason
“Make it look viral”
Vague. Lint and critique enforce quality, not vibes.
“Start the reel with a slow fade-in”
HOOK_LATENCY blocks render. The earliest Sequence must start at frame 30 or earlier — viewers thumb past dead openings.
“Animate `top` / `left` / `width` with interpolate()”
NON_HW_ACCEL_PROP blocks render. Layout-thrashing animation tanks smoothness. Use `transform: translateY/X` or `scale` on `opacity` instead.
“Match graphify exactly”
License forbids verbatim re-publish. Reference reels are pattern study only.
“Make it 10 minutes long”
Wrong product. ReelStack is 9:16 short-form (typically 30–120 s).
“My voiceover” (no path)
Claude has to ask. Wastes a turn — pass the absolute path.
“Skip the lint, just ship”
Defeats the entire product. The lint rules are why ReelStack reels look earned, not guessed. Errors block render; warnings inform.
“Show a demo clip in the middle”
Vague — no path, no BEAT key. Write: “demo.mp4 at BEATS.demo” so Claude can wrap it in a Sequence. The duration is already defined by your audio.
Drop one of these into Claude Code right after running npx @devinilabs/reelstack init, or just type the family slash command and let the menu walk you through. Either way, the skill triggers on family / preset names automatically — no wrapping prompt about ReelStack itself.
v1.3.1: motion-designer priming is built in. No need to prepend “act as a senior motion designer” or similar persona prompts — SKILL.md's Craft posture section tells Claude to treat the ≥4-layer motion floor as a floor (not a ceiling), use perpetual primitives in every anchor scene, and apply GSAP-flavored easings throughout. The bundled gsap-core and gsap-timeline companion skills reinforce the GSAP vocabulary.
03 · The five families
Five cinematic style DNAs.
Every reel descends from one. The family decides palette, allowed accents, signature primitives, variant overlay, and motion vocabulary. The preset decides frame budget, BEAT structure, and the scene composition.
Glass Iridescent
/reelstack-glass
Soft + General·7 reference reels·7 presets
Premium product reveal — underwater light caustics, glass surfaces, iridescent text shimmer. Default family for multimodal product reveals and SaaS announcements.
Late-night ad-film — zinc void, drifting spotlights, multi-brand accents permitted. The only family without an accent allowlist (multi-brand by design).
Every preset is modeled on a real Devini Labs reel that was already in production. Frame counts, hook copy, BEAT structures, and primitive composition are copied verbatim from the source reel — what changes between your scaffolded copy and the reference is the audio + on-screen content, not the timing or motion.
Preset
Source reel
Frames
Sec
Hook
Best for
Signature
graphify
glassref
GraphifyReel
1,956
65.2
Multimodal Claude understands the whole web. Graph everything.
Click any row to expand its BEAT keys, primitives, and notes. For full per-preset metadata + family palette, see docs/family-galleries/<family>.md.
05 · The 13 slash commands
Thin wrappers. Fast loops.
Each slash command composes context (palette, primitives, reference reel) and shells out to a CLI subcommand. The CLI is the work-horse; the slash commands are the conversation.
/reelstack-init
First-time setup. Verifies the license, checks Node 20+ / ffmpeg / whisper-cpp dependencies, scaffolds ~/.reelstack/, installs the skill, and creates a Demo.tsx so the buyer sees a working reel within 5 minutes.
Design Direction Advisor. When your brief is vague, this returns 3 differentiated family picks with mood, best-for examples, and presets — useful when you don't know which family fits the reel you want to build.
Required
"<brief>" (one-sentence description of the reel)
Internally
npx reelstack direction "<brief>"
Example
/reelstack-direction "Launching a privacy-first local AI tool for indie devs"
Common follow-ups
/reelstack-glass/reelstack-dark/reelstack-warm
/reelstack-glass
Scaffold a Glass Iridescent 9:16 reel. Light lavender + iridescent caustics, sonar rings, glass cards, floating glyphs. Default family for premium product reveals.
Convert a voiceover .wav into frame-accurate BEAT constants. Resamples to 16 kHz mono via ffmpeg, runs whisper-cli, parses the SRT output, emits a TypeScript const block keyed by phrase → frame number.
Required
<voiceover.wav>
Optional flags
--name=<varName>— Override the const variable name (default: BEATS)
Capture product screenshots or scroll-recordings from a URL into public/captures/<slug>/. Validates the URL, drives chrome-devtools MCP via the user's reel-capture skill, saves assets with conventional names (hero.png for stills, frame_0001.png for scroll).
Required
<url>
Optional flags
--scroll— Record a scroll-through frame sequence instead of a still
--name=<slug>— Override the public/captures/<slug>/ dir name
Validate a reel against ReelStack house rules — motion floors, IG safe zones, hero-text fit, audio lock, brand discipline. Surfaces violation list with line numbers.
Run a 5-dimension expert critique — palette · motion · timing · hierarchy · brand fit. Outputs a radar score (0–10 each) plus a Keep/Fix/Quick punch list. Use after /reelstack-lint passes when you want a deeper qualitative review.
Render a reel composition with platform-optimal flags (1080×1920 H.264, 8 Mbps for IG/TikTok, 9 Mbps for Shorts). Lints first; aborts on safe-zone or motion-floor violations unless --force is passed.
Required
<comp-id>
Optional flags
--platform=<name>— ig (default) | tiktok | shorts
--out=<path>— Override output path
--force— Skip pre-render lint failures and smoke check
--format=<list>— mp4 (default) | gif — comma-separated for both
--bgm=<path.mp3>— Background music file (mixed at -14 LUFS-ish)
--interpolate=<fps>— Override composition fps
--palette-optimize— Quantize GIF to 64 colors (default 256)
The graphify preset is the default scaffold; the same loop applies to any family/preset combo. Audio file goes in public/audio/; captures in public/captures/; icons in public/icons/; rendered MP4s in ./out/.
Step 01Buy + install
We email your license key (UUID) right after Razorpay confirms the payment. v1.2+ init runs a 4-tier readiness gate: (1) Node 20+ hard check, (2) ffmpeg + whisper-cpp — auto-install on macOS+Homebrew, print platform-specific commands on Linux (apt/dnf/pacman) or Windows (choco/scoop), (3) Remotion project bootstrap via npx create-video if missing, (4) smoke test that scaffolds a Demo and proves Remotion + ffmpeg actually load. The success banner is provable — every /reelstack-* command works after exit 0, or init exits non-zero with a clear remediation.
npx @devinilabs/reelstack init
Step 02Scaffold a reel
One slash command. Pick a family + preset + name + voiceover. The skill copies the preset template into ./src/<Name>.tsx and registers it in src/Root.tsx.
ffmpeg resamples to 16 kHz mono → whisper-cli transcribes → CLI emits a TypeScript const block keyed by phrase → frame number. Paste it at the top of your reel and replace every Sequence's from prop with BEATS.<key>.
/reelstack-beats public/audio/launch.wav
Step 04Iterate in Remotion Studio
Live preview at http://localhost:3000. Edit src/<Name>.tsx — the studio hot-reloads. The audio file in public/audio/ plays in sync; beats stay locked.
npm run dev
Step 05Lint + render
/reelstack-lint surfaces every house-rule violation with line numbers. Fix until clean, then render the platform variant. The CLI infers the source file from the comp ID, lints first (aborts on safety violations unless --force), runs a 3-frame smoke check, then ships an MP4 ready to post.
Asset-stripped Devini Labs production reels at ~/.reelstack/reference/<family>/<preset>.tsx. Their job is to give Claude — your Claude, not Anthropic's — studyable, complete examples of how each preset's primitives compose at production quality. Originals are not redistributed; the .tsx files ship intact but their imported assets (videos, captures, audio) are stripped.
0 of the 22 presets currently ship without a reference reel — they fall back to inline scaffolding only:
v1.x updates may add more — your purchase covers all of them.
How Claude uses them
When you scaffold a preset that has a reference, the slash command also reads reference/<family>/<preset>.tsx — so it can cite specific scenes during iteration ("the SonarRings stack at frame 240 in graphify"), not just file names.
Override with --reference
Want Claude to model a different preset's motion language? Pass --reference=<preset> when scaffolding. Useful when the scaffolded preset's reference is missing or doesn't capture the energy you want.
License terms (excerpt)
Study + adapt patterns — OK.
Copy short excerpts (single scene, motion combination, transition recipe) into your own reel — OK.
Verbatim re-publication of a reference reel as your own — NOT OK.
Removing REFERENCE-STRIP markers and reselling as a paid template — NOT OK.
08 · Audio-locking pipeline
Eyeballs drift. Frames don't.
Eyeballed beats drift 6+ seconds on a 90-second voiceover. The motion gets ahead of the audio (or behind), and every cut feels off. The /reelstack-beats command exists to make eyeballing impossible.
01
Input WAV
Place your voiceover in public/audio/. The CLI accepts mono or stereo at any sample rate — ffmpeg normalizes it next.
Whisper base.en mishears tech terms ("Claude" → "Cloud", "Remotion" → "Re-motion"). Use timings frame-for-frame; copy on-screen text from your script, not from the SRT.
Re-run /reelstack-beats after re-recording — beats from the old voiceover won't match a new take.
The audio file goes in ./public/audio/, never ./src/.
09 · Design discipline
Where the family DNAs live.
Eleven master rules apply to every reel in every family. Each family adds a variant overlay on top — the per-family typographic and motion-vocabulary tax.
7 master rules
Max one accent per family at <80% saturation (Dark exception)
Hardware-accel animation (transform + opacity only; lint-enforced as NON_HW_ACCEL_PROP)
Spring-physics defaults via utils/easing.ts
Complete-output discipline (no truncation in scaffolds)
Anti-generic placeholder copy
prefers-reduced-motion parity on every motion component
Replace the 5 ScreenshotFade `src` props in src/ThesisReel.tsx with the captured frames (frame_0001.png, frame_0480.png, frame_0860.png, frame_1240.png, frame_1620.png).
Record a voiceover reading the thesis. Lock motion.
/reelstack-beats public/audio/thesis.wav
Lint, critique, then render Shorts variant for higher bitrate.
/reelstack-render ThesisReel --platform=shorts
Render the IG variant (8 Mbps).
/reelstack-render MyReel --platform=ig
Render the TikTok variant (8 Mbps).
/reelstack-render MyReel --platform=tiktok
Render the Shorts variant (9 Mbps — slightly higher bitrate).
/reelstack-render MyReel --platform=shorts
Outputs: out/MyReel-ig.mp4, out/MyReel-tiktok.mp4, out/MyReel-shorts.mp4. Dimensions identical (1080×1920); only bitrate differs.
Scaffold the claudewatch preset (six-color scene palette).
Every animated component accepts reduceMotion?: boolean (default false). The MISSING_REDUCE_MOTION lint rule enforces this on user-authored components that import useCurrentFrame. Templates read the flag from Remotion's getInputProps() at module load.
/reelstack-render doesn't currently take --reduce-motion directly; use raw npx remotion render for the low-motion variant. Reels are rendered MP4s, so the runtime can't read prefers-reduced-motion — render both variants and serve the right one based on the consumer's preference (Instagram's app, the user's browser, etc.).
12 · Mental model
Two pieces pretending to be one.
ReelStack is a Claude Code skill ( ~/.claude/skills/reelstack/) that delegates to a Node CLI ( ~/.reelstack/). The skill owns the conversation; the CLI does the work. You interact with the skill; the CLI is invisible until you open out/<Name>-ig.mp4.
The skill
Lives at ~/.claude/skills/reelstack/. Owns the conversation. Each /reelstack-* slash command reads the family-gallery doc and the reference reel, then shells out to the CLI.
The CLI
Lives at ~/.reelstack/ (and via npx). Owns the work. Scaffolds reels, extracts beats, captures screenshots, fetches icons, lints, critiques, renders.
The data model
5 families × 22 presets × 13 slash commands × 14 lint rules × 22 reference reels (one per preset). Pinned to v1.4.0. Every v1.x update auto-flows to existing licenses.
Twelve known failure modes plus their fixes. If yours isn't here, email [email protected] with your reel file and the lint output — we'll add it.
Check the cached license file at `~/.reelstack/.license` (mode 600). Delete it and re-run init. If the key was emailed but rejected, contact [email protected] with your purchase email.
v1.2+: init's Tier 2 detects this and offers to install for you on macOS+Homebrew. On other platforms it prints the right command for your package manager and exits so you can install + retry. Manual install — macOS: `brew install ffmpeg`. Linux: `apt-get install ffmpeg` (Debian/Ubuntu) · `dnf install ffmpeg` (Fedora) · `pacman -S ffmpeg` (Arch). Windows: `choco install ffmpeg` or `scoop install ffmpeg`. Required by /reelstack-render and /reelstack-beats.
You declined the whisper install during `init`, OR the install ran but didn't put a binary on PATH. Fix: macOS: `brew install whisper-cpp`. Linux: build from source at github.com/ggerganov/whisper.cpp. Windows: build from source, or `scoop install whisper.cpp`. Then re-run `npx @devinilabs/reelstack init` so it can re-flip the state to OK.
Same as above — install via your platform's package manager, then run `npx @devinilabs/reelstack init` so the readiness gate records the dep as available. Required by /reelstack-beats.
macOS / Linux: `bash <(curl -L https://raw.githubusercontent.com/ggerganov/whisper.cpp/master/models/download-ggml-model.sh) base.en` in your project root. Windows (PowerShell): `Invoke-WebRequest -Uri https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base.en.bin -OutFile $env:TEMP\ggml-base.en.bin`.
The named step tells you which check failed. `scaffold-demo` = your `Root.tsx` doesn't accept the Demo composition (check that registerRoot exists). `remotion-compositions` = Remotion CLI couldn't load the project (likely `npm install` didn't complete or `tsconfig.json` is broken — try `rm -rf node_modules && npm install` and retry). `ffmpeg-version` = ffmpeg is installed but not executable (rare; reinstall). Pass `--skip-smoke` to bypass once you've diagnosed the cause.
Your project's `package.json` has a syntax error. Open it and fix the JSON (most often a trailing comma or missing quote). Or run `init` from a different directory.
Upgrade Node. With nvm: `nvm install 20 && nvm use 20`. With fnm: `fnm install 20 && fnm use 20`. Or fresh install from nodejs.org. Then re-run `init`.
Add `// reelstack-lint-ignore-line` immediately above the offending line. Use sparingly — most flagged hexes are real violations.
Critique scores motion + palette + timing of what's actually in the file; an unused BEATS const isn't penalized. Run `/reelstack-beats <vo.wav>` to populate it before trusting the critique number.
Open `src/Root.tsx` and confirm the new comp is registered as a `<Composition>` entry. The scaffolder should do this automatically; if it didn't, add it manually.
Increase Remotion's timeout: `npx remotion render <id> --timeout 60000`. Common cause: large `<Img />` reads from the filesystem during render.
Some openers genuinely start black — pass `--skip-smoke` to bypass. If a midpoint frame is also all-black, your composition is broken; check `npm run dev` first.
ffmpeg's `-target-bitrate` flag conflicts with `-crf` in some ffmpeg versions. Try `--platform=ig` (uses both flags) versus a raw `npx remotion render` invocation (uses only crf).
`npx` runs the package without globally installing. Either invoke as `npx @devinilabs/reelstack <cmd>` each time, or globally install: `npm install -g @devinilabs/reelstack`.
If you moved `~/.reelstack/`, run `npx @devinilabs/reelstack update` to refresh the symlinks. Reference reels live at `~/.reelstack/reference/<family>/<preset>.tsx`.
14 · Cheat sheet
Print this. Keep it next to your monitor.
Single-screen quick-reference. Cmd+P prints a clean black-on-white layout (animations, sidebar, and chrome are hidden in print).
All 13 slash commands
/reelstack-init
First-time setup: license + dep verify + Demo.tsx scaffold