--- name: remotion scope: common description: Use when a task involves Remotion compositions, Studio, Player, @remotion packages, programmatic video rendering, captions, media processing, maps, or Remotion and Mediabunny upgrades. requires: - assets metadata: aliases: - remotion-best-practices - remotion-captions - remotion-create - remotion-docs - remotion-interactivity - remotion-maps - remotion-markup - remotion-multimedia - remotion-render - remotion-saas - remotion-studio - remotion-upgrade --- # Remotion Build and maintain Remotion projects while preserving user changes. If a file changed unexpectedly, treat it as intentional unless the user confirms otherwise. ## Workflow 1. Inspect `package.json`, the lockfile, existing compositions, the current diff, and `npx remotion versions`. Reuse the package manager and project shape; keep every `remotion` / `@remotion/*` package on one exact version. 2. Confirm the requested output: composition/source changes, Studio preview, rendered media, an embedded Player, or a rendering service. 3. Implement deterministic, frame-driven visuals and keep render inputs serializable. 4. Preview in Studio. Render only when the user requests a media file. 5. Verify rendered media with `ffprobe` and inspect representative frames. 6. Report changed files, preview/render evidence, and the delivery receipt. In Prismer, a loose sandbox path is not a delivered result. ## Prismer artifact and delivery contract When the user requests rendered media, write the final file under `$PRISMER_ARTIFACTS_DIR` (the dispatch ``). Put project scaffolds, frames, probes, and other intermediates under `$PRISMER_SCRATCH_DIR` or the existing project tree. Then deliver each requested final file exactly once: ```bash cloud deliver "$PRISMER_ARTIFACTS_DIR/launch-video.mp4" ``` Writing or rendering a file does not attach it. A successful `cloud deliver` receipt is the delivery oracle. Do not deliver preview frames, temporary audio, or duplicate encodes unless the user requested them. If no dispatch artifact directory exists, keep the result in the user-approved project output path and report that delivery was unavailable rather than inventing a receipt. ## Project creation and compositions Do not scaffold over a non-empty project. When no suitable project exists, confirm Node.js and Git are available, then run: ```bash npx create-video@latest --yes --blank --no-tailwind my-video cd my-video npm install ``` Use a meaningful directory name. Add Tailwind only when the user asks for it or the project already uses it. Inspect the generated manifest, config, and global CSS before continuing: generator releases can still emit Tailwind dependencies and imports when `--no-tailwind` was requested. Remove those only when the project does not use them, and keep the Remotion package versions aligned. In Prismer sandbox images, use a command-scoped writable npm cache for every command that may install or invoke a missing package, including scaffolding, `npm ci`, `remotion add`, probes, and renders: ```bash npm_config_cache="${PRISMER_SCRATCH_DIR:-/tmp}/npm-cache" npm ci ``` Do not change the user's global npm configuration to work around a sandbox ownership mismatch. Keep static composition metadata inline: ```tsx ``` Use `calculateMetadata()` only when duration, dimensions, or props genuinely depend on inputs, remote data, or media inspection. Keep `defaultProps` inline so Studio can save prop edits back to code. For multi-scene videos, use named `` boundaries and derive all timing from one fps-aware plan. ## Frame-driven animation Drive rendered animation from `useCurrentFrame()`, `interpolate()`, springs, or easing. Do not use CSS transitions, CSS animations, wall-clock timers, or Tailwind animation utilities; they are not deterministic renders. ```tsx import { AbsoluteFill, Easing, Interactive, interpolate, useCurrentFrame, useVideoConfig, } from 'remotion'; export const Hero = () => { const frame = useCurrentFrame(); const {fps} = useVideoConfig(); return ( Launch day ); }; ``` Prefer the individual `scale`, `translate`, and `rotate` CSS properties over a composed `transform` string. Clamp both ends of finite animations unless extrapolation is intentional. ## Studio-editable markup Use `Interactive.*` for HTML and SVG elements that should be selectable, draggable, resized, rotated, styled, or keyframed in Studio. `` is already interactive. - Give each interactive element a short, hard-coded, descriptive `name`. - Keep one-off text directly inside the element. - Keep style objects, `interpolate()` ranges, outputs, easing, and extrapolation inline when Studio write-back matters. - Destructure only supported values such as `fps`, `width`, `height`, and `durationInFrames` from `useVideoConfig()`. - Avoid extracted style constants, object spreading, computed effect arrays, and arbitrary variables inside editable keyframe ranges. For custom components, look up the current `make-component-interactive` API in the official Remotion documentation before implementing it. ## Assets, media, and timing Put local assets in `public/` and reference them with `staticFile()`: ```tsx import {Audio, Video} from '@remotion/media'; import {AnimatedImage, CanvasImage, staticFile} from 'remotion'; export const MediaLayer = () => ( <>