Use when generating or modifying Remotion video code, creating demo videos, or working with the demo-video/ directory
82%
Does it follow best practices?
Impact
80%
1.50xAverage score across 3 eval scenarios
—
The risk profile of this skill
App Factory includes an integrated Remotion video pipeline for generating demo videos of built applications.
demo-video/ directory/factory video commanddemo-video/
├── src/
│ ├── index.ts # Remotion entry point
│ ├── Root.tsx # Composition registry
│ ├── compositions/
│ │ └── AppFactoryDemo.tsx # Main demo video (10s, 1920x1080)
│ └── components/
│ ├── Title.tsx # Animated title
│ ├── BulletPoints.tsx # Staggered highlights
│ ├── VerificationBadge.tsx # PASS badge
│ └── Footer.tsx # UTC timestamp
├── remotion.config.ts # Remotion configuration
└── package.json # Dependencies (Remotion v4.x)// CORRECT: Use useCurrentFrame() for all animations
const frame = useCurrentFrame();
const opacity = interpolate(frame, [0, 30], [0, 1], {
extrapolateRight: 'clamp',
});
// FORBIDDEN: CSS animations/transitions
// Never use: animation:, transition:, @keyframes// ALWAYS use extrapolation clamping
const value = interpolate(frame, [0, 60], [0, 100], {
extrapolateLeft: 'clamp',
extrapolateRight: 'clamp',
});// Use spring() for physics-based animations
const springValue = spring({
fps,
frame,
config: { damping: 200, stiffness: 100 },
durationInFrames: 40,
});new Date()timeZone: 'UTC' for all date formattingMath.random() or non-deterministic values// All compositions must follow this pattern
export const MyComposition: React.FC<Props> = (props) => {
const frame = useCurrentFrame();
const { fps, width, height, durationInFrames } = useVideoConfig();
return (
<AbsoluteFill style={{ backgroundColor: '#000' }}>
{/* Sequenced content */}
<Sequence from={0} durationInFrames={60}>
<Scene1 />
</Sequence>
<Sequence from={60} durationInFrames={60}>
<Scene2 />
</Sequence>
</AbsoluteFill>
);
};RUN_CERTIFICATE.json created with status: "PASS"post-run-certificate-video.mjsdemo/out/<slug>.mp4# Basic usage
node scripts/render-demo-video.mjs --cwd ./my-app --slug my-app
# With custom highlights
node scripts/render-demo-video.mjs \
--cwd ./my-app \
--slug my-app \
--title "My Amazing App" \
--highlights '["Feature 1", "Feature 2", "Feature 3"]'interface AppFactoryDemoProps {
title: string; // App name
slug: string; // URL-safe identifier
verifiedUrl: string; // Localhost URL that passed health check
timestamp: string; // ISO 8601 timestamp (UTC)
highlights: string[]; // 4-6 bullet points
certificateHash: string; // SHA256 of RUN_CERTIFICATE.json
}# Preview in Remotion Studio
cd demo-video && npm run studio
# Render specific composition
npx remotion render src/index.ts AppFactoryDemo output.mp4
# Check for TypeScript errors
npx tsc --noEmitconst fadeIn = interpolate(frame, [0, 30], [0, 1], {
extrapolateRight: 'clamp',
});
const fadeOut = interpolate(frame, [duration - 30, duration], [1, 0], {
extrapolateLeft: 'clamp',
extrapolateRight: 'clamp',
});
const opacity = fadeIn * fadeOut;items.map((item, index) => {
const delay = index * 10; // 10 frames between each
const itemOpacity = interpolate(
frame,
[delay, delay + 20],
[0, 1],
{ extrapolateLeft: 'clamp', extrapolateRight: 'clamp' }
);
return <Item key={index} style={{ opacity: itemOpacity }} />;
});const scaleSpring = spring({
fps,
frame: frame - startFrame,
config: { damping: 80, stiffness: 200 },
});
const scale = interpolate(scaleSpring, [0, 1], [0.8, 1]);| Code | Meaning | Resolution |
|---|---|---|
| FAC-006 | Video render failed | Check Remotion logs, verify ffmpeg installed |
| FAC-007 | Certificate missing | Run Local Run Proof first |
| FAC-008 | Props validation failed | Check prop types match schema |
NeverSight/learn-skills.dev
a144501
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.