
remotion-composition
Generates Remotion composition structure focusing ONLY on Sequence ordering, scene transitions, and duration mapping. Input is scene list with durations. Output is COMPOSITIONSTRUCTURE.md with Sequence layout and timing calculations. Use when organizing scenes or when asked to "structure composition", "layout scenes", "calculate timing".
- Installs
- 196
- Last 24h
- —
- Trending rank
- —
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/ncklrs/startup-os-skills --skill remotion-composition- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads remotion-composition automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
Remotion Composition
Generates composition structure documents that define how scenes are ordered, timed, and transitioned in a Remotion video. This skill focuses exclusively on Sequence layout and timing orchestration.
What This Skill Does
Generates composition structure for:
- Sequence layout — Ordering and positioning of scene Sequences
- Timing calculations — Start frames, end frames, duration for each scene
- Scene transitions — Overlap and crossfade timing between scenes
- Duration mapping — Converting seconds to frames for all scenes
- Timing constants — Structured timing object for constants.ts
Scope Boundaries
IN SCOPE:
- Sequence component organization
- Frame calculations for scene timing
- Scene overlap and transition timing
- Duration constant generation
- Scene ordering logic
OUT OF SCOPE:
- Scene component implementation (use
/remotion-component-gen) - Animation parameters (use
/remotion-animation) - Visual styling (colors, layouts)
- Asset management (use
/remotion-asset-coordinator)
Input/Output Formats
Input Format: Scene List with Durations
Accepts scene timing specifications:
Natural Language:
Scene 1 (Intro): 0-5 seconds
Scene 2 (Features): 5-15 seconds
Scene 3 (Demo): 15-25 seconds
Scene 4 (CTA): 25-30 seconds
Structured Format:
## Scene Timing
**Total Duration:** 30 seconds
**Frame Rate:** 30 fps
**Total Frames:** 900
**Scenes:**
1. Scene 1 - Intro: 5 seconds (0s - 5s)
2. Scene 2 - Features: 10 seconds (5s - 15s)
3. Scene 3 - Demo: 10 seconds (15s - 25s)
4. Scene 4 - CTA: 5 seconds (25s - 30s)
**Transitions:**
- Fade transition between scenes: 0.5 seconds (15 frames)
Output Format: COMPOSITION_STRUCTURE.md
Generates composition structure document:
# Composition Structure: ProductDemo
## Status
✅ Sequence layout defined
✅ Timing calculations complete
⏳ Ready for scene implementation
## Composition Overview
**Total Duration:** 30 seconds (900 frames @ 30fps)
**Scenes:** 4
**Transitions:** Crossfade (15 frames)
## Scene Timing Constants
```typescript
const FPS = 30;
export const SCENE_TIMING = {
intro: {
start: 0,
end: 150,
duration: 150,
// 0s - 5s
},
features: {
start: 150,
end: 450,
duration: 300,
// 5s - 15s
},
demo: {
start: 450,
end: 750,
duration: 300,
// 15s - 25s
},
cta: {
start: 750,
end: 900,
duration: 150,
// 25s - 30s
},
} as const;
// Transition timing
export const TRANSITIONS = {
crossfadeDuration: 15, // frames (0.5 seconds)
} as const;
Composition Layout
Main composition with Sequence structure:
import { AbsoluteFill, Sequence } from "remotion";
import { SCENE_TIMING } from "./constants";
import { Scene1Intro } from "./scenes/Scene1Intro";
import { Scene2Features } from "./scenes/Scene2Features";
import { Scene3Demo } from "./scenes/Scene3Demo";
import { Scene4CTA } from "./scenes/Scene4CTA";
export function ProductDemo() {
return (
<AbsoluteFill>
{/* Scene 1: Intro (0s - 5s) */}
<Sequence
from={SCENE_TIMING.intro.start}
durationInFrames={SCENE_TIMING.intro.duration}
>
<Scene1Intro />
</Sequence>
{/* Scene 2: Features (5s - 15s) */}
<Sequence
from={SCENE_TIMING.features.start}
durationInFrames={SCENE_TIMING.features.duration}
>
<Scene2Features />
</Sequence>
{/* Scene 3: Demo (15s - 25s) */}
<Sequence
from={SCENE_TIMING.demo.start}
durationInFrames={SCENE_TIMING.demo.duration}
>
<Scene3Demo />
</Sequence>
{/* Scene 4: CTA (25s - 30s) */}
<Sequence
from={SCENE_TIMING.cta.start}
durationInFrames={SCENE_TIMING.cta.duration}
>
<Scene4CTA />
</Sequence>
</AbsoluteFill>
);
}
Scene Timing Breakdown
| Scene | Name | Duration | Frames | Start Frame | End Frame |
|---|---|---|---|---|---|
| 1 | Intro | 5s | 150 | 0 | 150 |
| 2 | Features | 10s | 300 | 150 | 450 |
| 3 | Demo | 10s | 300 | 450 | 750 |
| 4 | CTA | 5s | 150 | 750 | 900 |
Total: 30 seconds (900 frames)
Timeline Visualization
Frame: 0 150 450 750 900
Time: 0s 5s 15s 25s 30s
|---------|---------|---------|---------|
Scene: | Intro | Features| Demo | CTA |
|---------|---------|---------|---------|
Next Steps
- Implement scenes via
/remotion-component-gen - Add transitions if needed (crossfades, wipes)
- Integrate constants into composition constants.ts
- Test timing in Remotion preview
- Adjust durations if scenes feel too fast/slow
Checklist
- Scene timing calculated
- Sequence layout defined
- Constants generated
- Timing constants structured
- Scene components implemented (next step)
- Transitions added (if needed)
- Timing tested in preview
## Composition Patterns
### Pattern 1: Sequential Scenes (No Overlap)
Standard sequential layout where scenes don't overlap:
```typescript
<Sequence from={0} durationInFrames={150}>
<Scene1 />
</Sequence>
<Sequence from={150} durationInFrames={300}>
<Scene2 />
</Sequence>
<Sequence from={450} durationInFrames={300}>
<Scene3 />
</Sequence>
Pattern 2: Overlapping Scenes (Crossfade)
Scenes overlap for smooth transitions:
const CROSSFADE = 15; // frames
// Scene 1: Full duration
<Sequence from={0} durationInFrames={150}>
<Scene1 />
</Sequence>
// Scene 2: Starts before Scene 1 ends
<Sequence from={150 - CROSSFADE} durationInFrames={300 + CROSSFADE}>
<Scene2 />
</Sequence>
// Scene 3: Starts before Scene 2 ends
<Sequence from={450 - CROSSFADE} durationInFrames={300 + CROSSFADE}>
<Scene3 />
</Sequence>
Pattern 3: Layered Composition
Background + foreground scenes running simultaneously:
{/* Background layer - runs full duration */}
<Sequence from={0} durationInFrames={900}>
<BackgroundScene />
</Sequence>
{/* Foreground scenes - sequential */}
<Sequence from={0} durationInFrames={150}>
<Scene1 />
</Sequence>
<Sequence from={150} durationInFrames={300}>
<Scene2 />
</Sequence>
Pattern 4: Nested Sequences
Sub-scenes within main scenes:
<Sequence from={0} durationInFrames={300}>
<AbsoluteFill>
{/* Sub-scene 1 */}
<Sequence from={0} durationInFrames={100}>
<Intro />
</Sequence>
{/* Sub-scene 2 */}
<Sequence from={100} durationInFrames={200}>
<MainContent />
</Sequence>
</AbsoluteFill>
</Sequence>
Timing Calculation Helpers
Common frame calculations:
// Convert seconds to frames
const secondsToFrames = (seconds: number, fps: number = 30): number =>
Math.round(seconds * fps);
// Calculate scene timing
interface SceneTiming {
start: number;
end: number;
duration: number;
}
const calculateSceneTiming = (
startSeconds: number,
durationSeconds: number,
fps: number = 30
): SceneTiming => {
const start = secondsToFrames(startSeconds, fps);
const duration = secondsToFrames(durationSeconds, fps);
const end = start + duration;
return { start, end, duration };
};
// Calculate crossfade overlap
const calculateCrossfade = (
scene1Start: number,
scene1Duration: number,
crossfadeDuration: number
) => ({
scene1: {
from: scene1Start,
durationInFrames: scene1Duration,
},
scene2: {
from: scene1Start + scene1Duration - crossfadeDuration,
durationInFrames: crossfadeDuration, // or more if scene is longer
},
});
// Validate total duration
const validateDuration = (
scenes: SceneTiming[],
expectedTotal: number
): boolean => {
const lastScene = scenes[scenes.length - 1];
return lastScene.end === expectedTotal;
};
Scene Timing Generation
Automated timing generation from scene list:
interface SceneSpec {
name: string;
durationSeconds: number;
}
const generateSceneTiming = (
scenes: SceneSpec[],
fps: number = 30
) => {
let currentFrame = 0;
const timing: Record<string, SceneTiming> = {};
for (const scene of scenes) {
const duration = secondsToFrames(scene.durationSeconds, fps);
timing[scene.name] = {
start: currentFrame,
end: currentFrame + duration,
duration,
};
currentFrame += duration;
}
return {
timing,
totalFrames: currentFrame,
totalSeconds: currentFrame / fps,
};
};
// Usage:
const scenes = [
{ name: 'intro', durationSeconds: 5 },
{ name: 'features', durationSeconds: 10 },
{ name: 'demo', durationSeconds: 10 },
{ name: 'cta', durationSeconds: 5 },
];
const result = generateSceneTiming(scenes, 30);
// Result:
// {
// timing: {
// intro: { start: 0, end: 150, duration: 150 },
// features: { start: 150, end: 450, duration: 300 },
// ...
// },
// totalFrames: 900,
// totalSeconds: 30,
// }
Transition Patterns
Crossfade Transition
Smooth opacity crossfade between scenes:
const CROSSFADE = 15;
// Scene 1 - fades out at end
<Sequence from={0} durationInFrames={150}>
<Scene1 crossfadeOut={CROSSFADE} />
</Sequence>
// Scene 2 - fades in at start
<Sequence from={150 - CROSSFADE} durationInFrames={300}>
<Scene2 crossfadeIn={CROSSFADE} />
</Sequence>
// In Scene component:
function Scene1({ crossfadeOut = 0 }) {
const frame = useCurrentFrame();
const { durationInFrames } = useVideoConfig();
const opacity = crossfadeOut > 0
? interpolate(
frame,
[durationInFrames - crossfadeOut, durationInFrames],
[1, 0],
{ extrapolateRight: 'clamp' }
)
: 1;
return <AbsoluteFill style={{ opacity }}>...</AbsoluteFill>;
}
Hard Cut Transition
No transition, instant scene change:
<Sequence from={0} durationInFrames={150}>
<Scene1 />
</Sequence>
<Sequence from={150} durationInFrames={300}>
<Scene2 />
</Sequence>
Slide Transition
One scene slides out while next slides in:
const TRANSITION_DURATION = 20;
<Sequence from={0} durationInFrames={150}>
<Scene1 slideOut={TRANSITION_DURATION} />
</Sequence>
<Sequence from={150 - TRANSITION_DURATION} durationInFrames={300}>
<Scene2 slideIn={TRANSITION_DURATION} />
</Sequence>
Duration Validation
Ensuring timing adds up correctly:
// Validation helper
const validateCompositionTiming = (
scenes: Record<string, SceneTiming>,
expectedDuration: number,
fps: number
): { valid: boolean; issues: string[] } => {
const issues: string[] = [];
// Check for gaps
const sceneList = Object.entries(scenes).sort((a, b) => a[1].start - b[1].start);
for (let i = 0; i < sceneList.length - 1; i++) {
const currentEnd = sceneList[i][1].end;
const nextStart = sceneList[i + 1][1].start;
if (nextStart > currentEnd) {
issues.push(`Gap detected: ${currentEnd} to ${nextStart} (${(nextStart - currentEnd) / fps}s)`);
}
if (nextStart < currentEnd) {
issues.push(`Overlap detected: ${sceneList[i][0]} and ${sceneList[i + 1][0]}`);
}
}
// Check total duration
const lastScene = sceneList[sceneList.length - 1][1];
if (lastScene.end !== expectedDuration) {
issues.push(
`Total duration mismatch: expected ${expectedDuration}, got ${lastScene.end} (${lastScene.end / fps}s)`
);
}
return {
valid: issues.length === 0,
issues,
};
};
Timeline Visualization Helper
Generate ASCII timeline:
const generateTimeline = (
scenes: Record<string, SceneTiming>,
fps: number,
width: number = 60
) => {
const lastScene = Object.values(scenes).reduce((max, scene) =>
scene.end > max ? scene.end : max, 0
);
const timeline: string[] = [];
// Frame markers
const frameMarkers = Array.from({ length: width + 1 }, (_, i) => {
const frame = Math.round((i / width) * lastScene);
return frame.toString().padStart(4);
}).join('');
timeline.push('Frame: ' + frameMarkers);
// Time markers
const timeMarkers = Array.from({ length: width + 1 }, (_, i) => {
const time = ((i / width) * lastScene) / fps;
return time.toFixed(1) + 's';
}).join(' ');
timeline.push('Time: ' + timeMarkers);
// Scene bars
for (const [name, timing] of Object.entries(scenes)) {
const startPos = Math.round((timing.start / lastScene) * width);
const endPos = Math.round((timing.end / lastScene) * width);
const bar = ' '.repeat(startPos) + '|' + '='.repeat(endPos - startPos - 1) + '|';
timeline.push(`${name.padEnd(8)}: ${bar}`);
}
return timeline.join('\n');
};
Best Practices
Timing Guidelines
// Minimum scene duration for readability
const MIN_SCENE_DURATION = 30; // 1 second at 30fps
// Standard transition duration
const STANDARD_TRANSITION = 15; // 0.5 seconds
// Maximum scene duration before pacing feels slow
const MAX_SCENE_DURATION = 600; // 20 seconds
// Recommended scene duration range
const IDEAL_SCENE_DURATION = {
min: 60, // 2 seconds
max: 300, // 10 seconds
};
Composition Organization
// Group related Sequences
// Good:
<>
{/* Background layer */}
<Sequence from={0} durationInFrames={900}>
<Background />
</Sequence>
{/* Content scenes */}
<Sequence from={0} durationInFrames={150}>
<Scene1 />
</Sequence>
<Sequence from={150} durationInFrames={300}>
<Scene2 />
</Sequence>
</>
// Bad: Mixed layers without organization
Integration Workflow
- Define scene durations → Input to this skill
- Generate composition structure → COMPOSITION_STRUCTURE.md
- Add to composition file (index.tsx)
- Add timing to constants (constants.ts)
- Implement scenes via
/remotion-component-gen - Test timing in preview
- Adjust if needed and regenerate
Integration with Other Skills
This skill coordinates with:
remotion-composition (this skill)
↓ outputs: COMPOSITION_STRUCTURE.md
remotion-component-gen
↓ implements scenes with timing awareness
remotion-animation
↓ animation timing works within scene durations
Works with:
/motion-designer— Scene timing from design specs/remotion-scaffold— Structure added to composition file/remotion-animation— Timing coordinates with animation configs/remotion-component-gen— Scenes fit within calculated durations/remotion-spec-translator— Orchestrates this skill in pipeline
This skill provides precise composition structure and timing calculations that ensure smooth, well-paced Remotion videos.
FAQ
What does the remotion-composition skill do?
Generates Remotion composition structure focusing ONLY on Sequence ordering, scene transitions, and duration mapping. Input is scene list with durations. Output is COMPOSITIONSTRUCTURE.md with Sequence layout and timing calculations. Use when organizing scenes or when asked to "structure composition", "layout scenes", "calculate timing".
How do I install remotion-composition?
Run npx skills add https://github.com/ncklrs/startup-os-skills --skill remotion-composition in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/remotion-composition/ (personal) or .claude/skills/remotion-composition/ (project).
Which AI agents can use remotion-composition?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is remotion-composition safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains remotion-composition?
It is published by ncklrs in ncklrs/startup-os-skills. It has 196 recorded installs.
More from ncklrs/startup-os-skills
community-builder
ncklrs/startup-os-skills
Expert community-led growth and community management guidance. Use when building developer communities, Discord/Slack communities, online communities, managing community platforms, designing member onboarding, creating engagement programs, running ambassador programs, measuring community health, setting up moderation systems, or implementing DevRel strategies. Use for community-led growth, member activation, user-generated content programs, and community governance.
proposal-writer
ncklrs/startup-os-skills
Expert sales proposal and pricing presentation strategist. Use when writing proposals, executive summaries, ROI business cases, pricing presentations, SOWs (Statement of Work), RFP responses, or competitive positioning documents. Covers proposal structure, terms positioning, design formatting, follow-up strategy, and win-rate optimization.
motion-designer
ncklrs/startup-os-skills
Advanced motion designer with decades of After Effects and motion graphics experience, specialized in creating engaging video specifications for Remotion. Use when creating video specs, planning motion graphics, designing animations, or when asked to "create a video", "design motion graphics", "plan video content", or "spec out a video". Produces detailed scene-by-scene specifications with timing, audio, sound effects, and animation descriptions.
website-copy-specialist
ncklrs/startup-os-skills
Expert website copywriting for SaaS and B2B companies. Use when writing homepage copy, feature pages, about pages, pricing pages, comparison pages, product tours, integration pages, use case pages, demo/contact pages, or navigation microcopy. Use for website messaging hierarchy, value proposition development, and page-level conversion optimization.
vsl-storyboard-writer
ncklrs/startup-os-skills
Open the skill to read its SKILL.md instructions.
remotion-animation
ncklrs/startup-os-skills
Open the skill to read its SKILL.md instructions.
Popular media & creative skills
hyperframes
heygen-com/hyperframes
Read first to make, edit, animate or render any video with HyperFrames (HTML rendered to video), including launch films, explainers, music videos, charts, maps, vertical clips, title cards, captions and overlays. Holds the render contract, the work loop and what each kind of video needs.
media-use
heygen-com/hyperframes
Get or make any media for a HyperFrames video - music, sound effects, images, icons, logos, voiceover, avatar and generated video, transcripts, cutouts, colour grades and looks - with HeyGen or free local tools, and mix placed audio. Also for footage that looks dark, flat or dull, or should be stylized or hidden.
hyperframes-registry
heygen-com/hyperframes
About 450 ready-made HyperFrames blocks and components installed as editable source - transitions, overlays, titles, kinetic type, captions, charts, map overlays, 3D, camera moves. Use it before hand-building any named visual (CRT scanlines, glitch, film grain, a chart); also for hyperframes add and catalog.
hyperframes-creative
heygen-com/hyperframes
Non-animation creative direction for HyperFrames videos. Use for design spec (frame.md / design.md) handling, palettes, typography, narration, beat planning, audio-reactive visuals, composition patterns, and brand / style decisions. For atomic motion patterns and scene blueprints, use hyperframes-animation.
ai-video-generation
101-skills/superpowers
Generate AI videos with Google Veo, Seedance 2.0, HappyHorse, Wan, Grok and 40+ models via inference.sh CLI. Models: Veo 3.1, Veo 3, Seedance 2.0, HappyHorse 1.0, Wan 2.5, Grok Imagine Video, OmniHuman, Fabric, HunyuanVideo. Capabilities: text-to-video, image-to-video, reference-to-video, video editing, lipsync, avatar animation, video upscaling, foley sound. Use for: social media videos, marketing content, explainer videos, product demos, AI avatars. Triggers: video generation, ai video, text to video, image to video, veo, animate image, video from image, ai animation, video generator, generate video, t2v, i2v, ai video maker, create video with ai, runway alternative, pika alternative, sora alternative, kling alternative, seedance, happyhorse
ai-image-generation
101-skills/superpowers
Generate AI images with GPT-Image-2, FLUX, Gemini, Grok, Seedream, Reve and 50+ models via inference.sh CLI. Models: GPT-Image-2, FLUX Dev LoRA, FLUX.2 Klein LoRA, Gemini 3 Pro Image, Grok Imagine, Seedream 4.5, Reve, ImagineArt. Capabilities: text-to-image, image-to-image, inpainting, LoRA, image editing, upscaling, text rendering. Use for: AI art, product mockups, concept art, social media graphics, marketing visuals, illustrations. Triggers: flux, image generation, ai image, text to image, stable diffusion, generate image, ai art, midjourney alternative, dall-e alternative, text2img, t2i, image generator, ai picture, create image with ai, generative ai, ai illustration, grok image, gemini image, gpt image, openai image, chatgpt image