Remotion best practices
npx -y skills add tRollNhard/1st --skill remotion-best-practicesAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Best practices for building videos with Remotion (React-based video framework)
SKILL.md
3.3 KB, as published. Nobody here has run it
Remotion Best Practices
Composition Setup
- Always define
width,height,durationInFrames, andfpsexplicitly on<Composition>. - Use
fps: 30for most content;fps: 60for motion-heavy or gaming content. - Keep compositions focused — split long videos into multiple compositions and stitch with
<Series>or<Sequence>.
<Composition
id="MyVideo"
component={MyVideo}
durationInFrames={150}
fps={30}
width={1920}
height={1080}
/>
Timing & Animation
- Use
useCurrentFrame()andinterpolate()for all animations — never use CSS transitions orsetTimeout. - Clamp
interpolate()output withextrapolateLeft: "clamp"andextrapolateRight: "clamp"to avoid runaway values. - Use
<Sequence from={} durationInFrames={}>to offset and scope child timing.
const frame = useCurrentFrame();
const opacity = interpolate(frame, [0, 20], [0, 1], {
extrapolateLeft: "clamp",
extrapolateRight: "clamp",
});
Assets
- Wrap all static assets with
staticFile()— never use raw relative paths. - Preload audio and video with
prefetch()or<Preload>to avoid rendering gaps. - Use
<OffthreadVideo>instead of<Video>for better frame-accurate rendering during export.
import { staticFile } from "remotion";
<Img src={staticFile("logo.png")} />
<OffthreadVideo src={staticFile("clip.mp4")} />
Audio
- Use
<Audio>withstartFromandendAt(in frames) to trim clips. - Set
volumeas a function of frame for fades:volume={(f) => interpolate(f, [0, 10], [0, 1])}. - Use
<Sequence>to offset audio start time rather than manipulatingstartFromwith manual offsets.
Performance
- Avoid expensive computations inside render — memoize with
useMemo. - Don't load or fetch data at render time; pass all data as composition
defaultProps. - Use
delayRender/continueRenderfor async data fetching before rendering starts.
const handle = delayRender();
useEffect(() => {
fetchData().then((data) => {
setData(data);
continueRender(handle);
});
}, []);
Props & Schema
- Define a Zod schema for composition props and pass it via the
schemaprop on<Composition>. - This enables type-safe props in the Remotion Studio UI and CLI.
import { z } from "zod";
const schema = z.object({ title: z.string(), color: z.string() });
<Composition schema={schema} defaultProps={{ title: "Hello", color: "#fff" }} />
Rendering
- Use
npx remotion renderfor single renders; use Lambda (@remotion/lambda) for parallel/cloud rendering. - Pass
--concurrencyto tune CPU usage for local renders. - For programmatic rendering, use
renderMedia()from@remotion/renderer.
Common Pitfalls
- Non-determinism: never use
Math.random(),Date.now(), ornew Date()— output must be frame-deterministic. - Font loading: use
loadFont()from@remotion/google-fontsor calldelayRenderuntil custom fonts are ready. - Spring animations: use
spring()from Remotion, not fromreact-springorframer-motion— those are not frame-deterministic. - Missing continueRender: always pair every
delayRender()with acontinueRender(), or rendering will hang.