
Remotion Best Practices
Add Three.js and React Three Fiber 3D scenes to Remotion videos without render flicker or broken animation timing.
Install
npx skills add https://github.com/remotion-dev/remotion --skill remotion-best-practicesWhat is this skill?
- Documents install via `npx|bunx|yarn|pnpm remotion add @remotion/three` for npm, bun, yarn, and pnpm
- Requires wrapping all 3D content in `<ThreeCanvas>` with `width` and `height` from `useVideoConfig()`
- Requires explicit lighting (e.g. ambientLight + directionalLight) inside ThreeCanvas
- Hard rule: no shader, model, or scene motion unless driven by Remotion’s `useCurrentFrame()`—independent animation cause
- Points agents to standard React Three Fiber and Three.js practices outside Remotion-specific constraints
Adoption & trust: 54 installs on skills.sh; 49.4k GitHub stars; 2/3 security scanners passed (skills.sh audits).
Recommended Skills
Video Editagentspace-so/runcomfy-agent-skills
Image To Videoagentspace-so/runcomfy-agent-skills
Image Editagentspace-so/runcomfy-agent-skills
Flux Kontextagentspace-so/runcomfy-agent-skills
Nano Banana 2agentspace-so/runcomfy-agent-skills
Nano Banana Editagentspace-so/runcomfy-agent-skills
Journey fit
Primary fit
Solo builders implement programmatic video scenes during the build phase when composing Remotion React code for export. The skill centers on JSX composition—ThreeCanvas, meshes, and lighting—inside the Remotion frontend layer rather than backend or ops.
Common Questions / FAQ
Is Remotion Best Practices safe to install?
skills.sh reports 2 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.
SKILL.md
READMESKILL.md - Remotion Best Practices
# Using Three.js and React Three Fiber in Remotion Follow React Three Fiber and Three.js best practices. Only the following Remotion-specific rules need to be followed: ## Prerequisites First, the `@remotion/three` package needs to be installed. If it is not, use the following command: ```bash npx remotion add @remotion/three # If project uses npm bunx remotion add @remotion/three # If project uses bun yarn remotion add @remotion/three # If project uses yarn pnpm exec remotion add @remotion/three # If project uses pnpm ``` ## Using ThreeCanvas You MUST wrap 3D content in `<ThreeCanvas>` and include proper lighting. `<ThreeCanvas>` MUST have a `width` and `height` prop. ```tsx import { ThreeCanvas } from "@remotion/three"; import { useVideoConfig } from "remotion"; const { width, height } = useVideoConfig(); <ThreeCanvas width={width} height={height}> <ambientLight intensity={0.4} /> <directionalLight position={[5, 5, 5]} intensity={0.8} /> <mesh> <sphereGeometry args={[1, 32, 32]} /> <meshStandardMaterial color="red" /> </mesh> </ThreeCanvas>; ``` ## No animations not driven by `useCurrentFrame()` Shaders, models etc MUST NOT animate by themselves. No animations are allowed unless they are driven by `useCurrentFrame()`. Otherwise, it will cause flickering during rendering. Using `useFrame()` from `@react-three/fiber` is forbidden. ## Animate using `useCurrentFrame()` Use `useCurrentFrame()` to perform animations. ```tsx const frame = useCurrentFrame(); const rotationY = frame * 0.02; <mesh rotation={[0, rotationY, 0]}> <boxGeometry args={[2, 2, 2]} /> <meshStandardMaterial color="#4a9eff" /> </mesh>; ``` ## Using `<Sequence>` inside `<ThreeCanvas>` The `layout` prop of any `<Sequence>` inside a `<ThreeCanvas>` must be set to `none`. ```tsx import { Sequence } from "remotion"; import { ThreeCanvas } from "@remotion/three"; const { width, height } = useVideoConfig(); <ThreeCanvas width={width} height={height}> <Sequence layout="none"> <mesh> <boxGeometry args={[2, 2, 2]} /> <meshStandardMaterial color="#4a9eff" /> </mesh> </Sequence> </ThreeCanvas>; ``` import {loadFont} from '@remotion/google-fonts/Inter'; import {AbsoluteFill, spring, useCurrentFrame, useVideoConfig} from 'remotion'; const {fontFamily} = loadFont(); const COLOR_BAR = '#D4AF37'; const COLOR_TEXT = '#ffffff'; const COLOR_MUTED = '#888888'; const COLOR_BG = '#0a0a0a'; const COLOR_AXIS = '#333333'; // Ideal composition size: 1280x720 const Title: React.FC<{children: React.ReactNode}> = ({children}) => ( <div style={{textAlign: 'center', marginBottom: 40}}> <div style={{color: COLOR_TEXT, fontSize: 48, fontWeight: 600}}> {children} </div> </div> ); const YAxis: React.FC<{steps: number[]; height: number}> = ({ steps, height, }) => ( <div style={{ display: 'flex', flexDirection: 'column', justifyContent: 'space-between', height, paddingRight: 16, }} > {steps .slice() .reverse() .map((step) => ( <div key={step} style={{ color: COLOR_MUTED, fontSize: 20, textAlign: 'right', }} > {step.toLocaleString()} </div> ))} </div> ); const Bar: React.FC<{ height: number; progress: number; }> = ({height, progress}) => ( <div style={{ flex: 1, display: 'flex', flexDirection: 'column', justifyContent: 'flex-end', }} > <div style={{ width: '100%', height, backgroundColor: COLOR_BAR, borderRadius: '8px 8px 0 0', opacity: progress, }} /> </div> ); const XAxis: React.FC<{ children: React.ReactNode; labels: string[]; height: number; }> = ({children, labels, height}) => ( <div style={{flex: 1, display: 'flex', flexDirection: 'column'}}> <div style={{ display: 'flex', alignItems: 'flex-end', gap: 16, height,