skills/golem-powers/_archive/video-showcase/SKILL.md
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.
npx skillsauth add etanhey/golems video-showcaseInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Create polished 60-90 second product showcase videos programmatically using React + Remotion.
~/Gits/contentGolem/remotion/brew install ffmpeg)| 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) |
Collect from user:
remotion/public/)| 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 |
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>
);
};
# 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/Shorts
interpolate, spring, useCurrentFrame)setTimeout/setInterval — Remotion is deterministic, frame-by-frame<Sequence from={N}> for timing — not conditional rendering based on timestaticFile() for local assets — files go in public/ directoryspring() for natural motion — not linear interpolate for UI elementsextrapolateRight: 'clamp' — always clamp to prevent values going past targetconst opacity = interpolate(frame, [0, 2 * fps], [0, 1], { extrapolateRight: 'clamp' });
const translateX = spring({ frame, fps, from: -100, to: 0, config: { damping: 12 } });
{features.map((f, i) => (
<Sequence from={startFrame + i * staggerDelay} key={i}>
<AnimatedFeature text={f} />
</Sequence>
))}
const scale = interpolate(frame, [0, duration], [1, 1.15], { extrapolateRight: 'clamp' });
const translateY = interpolate(frame, [0, duration], [0, -50], { extrapolateRight: 'clamp' });
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,
});
}
| Platform | Resolution | Codec | FPS | Notes | |----------|-----------|-------|-----|-------| | LinkedIn | 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 |
/content skill — for text content pipeline/linkedin-post skill — for LinkedIn-specific postingtools
The human-eval UX contract for Phoenix views: turn-by-turn scrollable replay (not a scorecard), hide-but-copyable IDs, collapsed thinking, identity chips, tool filters, tiny frozen starter datasets, mark-wrong-in-thread, mobile-first. Use when: building or reviewing ANY Phoenix/eval view, annotation UI, session replay, or human-grading surface. Triggers: phoenix view, eval UI, annotation view, session replay, human eval UX, grading interface. NOT for: Phoenix data pipelines/ingest (capture scripts have their own specs).
tools
macOS systems specialist — AppKit NSPanel architecture, launchd services, socket activation, MCP bridge resilience, syspolicyd, and high-frequency SwiftUI dashboards. Use when building menu-bar apps, LaunchAgents, debugging syspolicyd/Gatekeeper/TCC, resilient UDS/MCP bridges, or SwiftUI dashboards at 10Hz+.
development
Bulk LLM-judging protocol for fleet-dispatched verdict runs (KG cluster, eval harness). Use when: dispatching or running judge workers (J1/J2/RT), planning bulk-apply from verdict JSONL, or triaging evidence_degraded outputs. Triggers: judge fleet, bulk judge, R3 verdicts, kg-judge, RT gate, evidence_degraded. NOT for: single-item code review, Phoenix view UX (use phoenix-human-view), or non-judge eval pipelines.
development
Quiet-down protocol for sprint close: when the fleet wraps, delete ALL polling crons and monitors, send ONE final dashboard + ONE message, then go SILENT. Use when: fleet wraps, all workers done, overnight queue exhausted, sprint close, Etan asleep/away with nothing approved left. Triggers: fleet wrap, wrap the fleet, stand down, going quiet, sprint close. NOT for: mid-sprint monitoring (keep your loops), spawning a successor (use /session-handoff first).