/video-showcase
Create product/project showcase videos using Remotion (React). Takes project description + screenshots → generates compositions → renders MP4. Use when asked to make demo videos, product showcases, or animated project walkthroughs.
$ golems-cli skills install video-showcaseUpdated 2 weeks ago
Create polished 60-90 second product showcase videos programmatically using React + Remotion.
Prerequisites
- Remotion project initialized in
~/Gits/contentGolem/remotion/ - ffmpeg installed (
brew install ffmpeg) - Chrome/Chromium for headless rendering (Remotion bundles this)
Quick Reference
| Action | Command |
|---|---|
| Preview | cd ~/Gits/contentGolem/remotion && npx remotion preview |
| Render | npx remotion render <CompositionId> out/video.mp4 --props='{"title":"My Project"}' |
| Batch render | Use renderMedia() API in a script (see below) |
Workflow
1. Gather Inputs
Collect from user:
- Project name and tagline
- Screenshots (2-5 key screens, placed in
remotion/public/) - Key features (3-5 bullet points)
- Tech stack (for badges/icons)
- Color palette (or extract from screenshots)
- Duration preference (30s / 60s / 90s)
2. Choose Template
| Template | Best For | Duration |
|---|---|---|
ProductHero | SaaS/web app with screenshots | 60s |
CodeWalkthrough | Developer tools, CLI, libraries | 90s |
BeforeAfter | Redesigns, improvements | 45s |
MetricShowcase | Growth, performance, stats | 30s |
ArchitectureDiagram | System design, infrastructure | 60s |
3. Generate Composition
Create a new TSX composition file in remotion/src/compositions/:
import { useCurrentFrame, useVideoConfig, interpolate, spring, Sequence, AbsoluteFill, Img } from "remotion";
import { staticFile } from "remotion";
type Props = {
title: string;
tagline: string;
features: string[];
screenshots: string[]; // filenames in public/
colors: { primary: string; bg: string; text: string };
};
export const ProductHero: React.FC<Props> = ({ title, tagline, features, screenshots, colors }) => {
const frame = useCurrentFrame();
const { fps } = useVideoConfig();
// Intro: title + tagline fade in (0-2s)
// Screenshots: pan/zoom through each (2-8s per screenshot)
// Features: slide in one by one (2s each)
// Outro: call to action (last 3s)
return (
<AbsoluteFill style={{ backgroundColor: colors.bg }}>
{/* Build composition here */}
</AbsoluteFill>
);
};4. Render
# Preview in browser
npx remotion preview
# Render to MP4
npx remotion render ProductHero out/showcase.mp4 \
--props='{"title":"My App","tagline":"Ship faster","features":["Fast","Reliable","Beautiful"],"screenshots":["screen1.png","screen2.png"],"colors":{"primary":"#3B82F6","bg":"#0F172A","text":"#F8FAFC"}}'
# Render for specific platform
npx remotion render ProductHero out/linkedin.mp4 --width=1920 --height=1080 # LinkedIn
npx remotion render ProductHero out/twitter.mp4 --width=1280 --height=720 # Twitter/X
npx remotion render ProductHero out/short.mp4 --width=1080 --height=1920 # Reels/ShortsFull SKILL.md source — includes LLM directives, anti-patterns, and technical instructions stripped from the Overview tab.
Create polished 60-90 second product showcase videos programmatically using React + Remotion.
Prerequisites
- Remotion project initialized in
~/Gits/contentGolem/remotion/ - ffmpeg installed (
brew install ffmpeg) - Chrome/Chromium for headless rendering (Remotion bundles this)
Quick Reference
| Action | Command |
|---|---|
| Preview | cd ~/Gits/contentGolem/remotion && npx remotion preview |
| Render | npx remotion render <CompositionId> out/video.mp4 --props='{"title":"My Project"}' |
| Batch render | Use renderMedia() API in a script (see below) |
Workflow
1. Gather Inputs
Collect from user:
- Project name and tagline
- Screenshots (2-5 key screens, placed in
remotion/public/) - Key features (3-5 bullet points)
- Tech stack (for badges/icons)
- Color palette (or extract from screenshots)
- Duration preference (30s / 60s / 90s)
2. Choose Template
| Template | Best For | Duration |
|---|---|---|
ProductHero | SaaS/web app with screenshots | 60s |
CodeWalkthrough | Developer tools, CLI, libraries | 90s |
BeforeAfter | Redesigns, improvements | 45s |
MetricShowcase | Growth, performance, stats | 30s |
ArchitectureDiagram | System design, infrastructure | 60s |
3. Generate Composition
Create a new TSX composition file in remotion/src/compositions/:
import { useCurrentFrame, useVideoConfig, interpolate, spring, Sequence, AbsoluteFill, Img } from "remotion";
import { staticFile } from "remotion";
type Props = {
title: string;
tagline: string;
features: string[];
screenshots: string[]; // filenames in public/
colors: { primary: string; bg: string; text: string };
};
export const ProductHero: React.FC<Props> = ({ title, tagline, features, screenshots, colors }) => {
const frame = useCurrentFrame();
const { fps } = useVideoConfig();
// Intro: title + tagline fade in (0-2s)
// Screenshots: pan/zoom through each (2-8s per screenshot)
// Features: slide in one by one (2s each)
// Outro: call to action (last 3s)
return (
<AbsoluteFill style={{ backgroundColor: colors.bg }}>
{/* Build composition here */}
</AbsoluteFill>
);
};4. Render
# Preview in browser
npx remotion preview
# Render to MP4
npx remotion render ProductHero out/showcase.mp4 \
--props='{"title":"My App","tagline":"Ship faster","features":["Fast","Reliable","Beautiful"],"screenshots":["screen1.png","screen2.png"],"colors":{"primary":"#3B82F6","bg":"#0F172A","text":"#F8FAFC"}}'
# Render for specific platform
npx remotion render ProductHero out/linkedin.mp4 --width=1920 --height=1080 # LinkedIn
npx remotion render ProductHero out/twitter.mp4 --width=1280 --height=720 # Twitter/X
npx remotion render ProductHero out/short.mp4 --width=1080 --height=1920 # Reels/ShortsCritical Remotion Rules
- NO CSS/Tailwind animations — all animation MUST be frame-based (
interpolate,spring,useCurrentFrame) - No
setTimeout/setInterval— Remotion is deterministic, frame-by-frame - Use
<Sequence from={N}>for timing — not conditional rendering based on time - Use
staticFile()for local assets — files go inpublic/directory - Use
spring()for natural motion — not linearinterpolatefor UI elements extrapolateRight: 'clamp'— always clamp to prevent values going past target- Props are JSON-serializable — no functions, no React elements in props
Animation Patterns
Fade In
const opacity = interpolate(frame, [0, 2 * fps], [0, 1], { extrapolateRight: 'clamp' });Spring Slide
const translateX = spring({ frame, fps, from: -100, to: 0, config: { damping: 12 } });Staggered List
{features.map((f, i) => (
<Sequence from={startFrame + i * staggerDelay} key={i}>
<AnimatedFeature text={f} />
</Sequence>
))}Screenshot Pan/Zoom
const scale = interpolate(frame, [0, duration], [1, 1.15], { extrapolateRight: 'clamp' });
const translateY = interpolate(frame, [0, duration], [0, -50], { extrapolateRight: 'clamp' });Data-Driven Batch Rendering
import { renderMedia, selectComposition } from '@remotion/renderer';
const projects = [
{ title: "Project A", screenshots: ["a1.png", "a2.png"], ... },
{ title: "Project B", screenshots: ["b1.png", "b2.png"], ... },
];
for (const project of projects) {
const composition = await selectComposition({
serveUrl: bundleLocation,
id: 'ProductHero',
inputProps: project,
});
await renderMedia({
composition,
serveUrl: bundleLocation,
codec: 'h264',
outputLocation: `out/${project.title}.mp4`,
inputProps: project,
});
}Export Settings by Platform
| Platform | Resolution | Codec | FPS | Notes |
|---|---|---|---|---|
| 1920x1080 | h264 | 30 | Max 10 min, <200MB | |
| Twitter/X | 1280x720 | h264 | 30 | Max 2:20, <512MB |
| YouTube | 1920x1080 | h264 | 30 | 16:9 preferred |
| Reels/Shorts | 1080x1920 | h264 | 30 | 9:16 vertical |
| GitHub README | 800x600 | gif | 15 | Keep <10MB |
See Also
- Remotion docs
/contentskill — for text content pipeline/linkedin-postskill — for LinkedIn-specific posting
Best Pass Rate
75%
Cursor
Assertions
12
6 models tested
Avg Cost / Run
$0.0737
across models
Fastest (p50)
2.4s
Haiku 4.5
Behavior Evals
Phase 2 baseline — skill quality on ClaudeBehavior Baseline
Adapter Evals
Phase 2C — cross-AI portabilityAdapter Portability
| Assertion | Opus 4.6 | Sonnet 4.6 | Haiku 4.5 | Codex | Cursor | Kiro | Consensus |
|---|---|---|---|---|---|---|---|
| generates-tsx-composition | 5/6 | ||||||
| uses-remotion-frame-api | 4/6 | ||||||
| uses-sequence-for-timing | 3/6 | ||||||
| uses-static-file-for-assets | 4/6 | ||||||
| renders-to-mp4 | 3/6 | ||||||
| clamps-extrapolation | 5/6 | ||||||
| rejects-css-animations | 3/6 | ||||||
| uses-frame-based-animation-anyway | 2/6 | ||||||
| no-settimeout-setinterval | 5/6 | ||||||
| uses-batch-render-api | 5/6 | ||||||
| separate-output-per-project | 5/6 | ||||||
| json-serializable-props | 4/6 |
Token Usage
Cost per Run
| Model | Input Tokens | Output Tokens | Cost / Run | Cost / 1K Runs |
|---|---|---|---|---|
| Opus 4.6 | 2,604 | 1,922 | $0.1832 | $183.20 |
| Sonnet 4.6 | 3,216 | 3,321 | $0.0595 | $59.50 |
| Haiku 4.5 | 2,365 | 2,277 | $0.0034 | $3.40 |
| Codex | 2,774 | 2,967 | $0.0732 | $73.20 |
| Cursor | 5,456 | 3,772 | $0.0822 | $82.20 |
| Kiro | 2,055 | 2,862 | $0.0405 | $40.50 |
Response Time (p50)
Response Time (p95)
| Model | p50 | p95 | Overhead |
|---|---|---|---|
| Opus 4.6 | 9.4s | 17.3s | +84% |
| Sonnet 4.6 | 3.6s | 7.2s | +100% |
| Haiku 4.5 | 2.4s | 4.1s | +71% |
| Codex | 6.1s | 11.0s | +82% |
| Cursor | 4.0s | 7.1s | +77% |
| Kiro | 2.6s | 5.0s | +91% |
Last evaluated: 2026-03-12 · Data is generated from skill assertions (real cross-model benchmarks coming soon)
Changelog entries are derived from eval runs and skill version updates. Full cascading changelog (Phase 4D) coming soon.
Best Pass Rate
75%
Assertions
12
Models Tested
6
Evals Run
3
- +Initial release to Golems skill library
- +12 assertions across 3 eval scenarios