Use when generating or modifying Remotion video code, creating demo videos, or working with the demo-video/ directory
80
Quality
78%
Does it follow best practices?
Impact
80%
1.50xAverage score across 3 eval scenarios
Passed
No known issues
Optimize this skill with Tessl
npx tessl skill review --optimize ./data/skills-md/0xaxiom/appfactory/remotion/SKILL.mdApp 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 |
5342bca
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.