{"id":"74e7359f-9a97-49b6-b3a8-6fd4d1b1ecc0","shortId":"Ma3d8W","kind":"skill","title":"remotion-best-practices","tagline":"Programmatic React video best practices for Remotion. Use this skill whenever the user is writing, debugging, or rendering Remotion code — compositions, useCurrentFrame animations, interpolate, spring, Sequence timing, <Img>/<Video>/<Audio> from @remotion/media, staticFile, calcu","description":"# Remotion Best Practices\n\nDomain-specific knowledge for writing, animating, and rendering Remotion videos in React. Mirrored from the upstream `remotion-dev/skills` and `remotion-dev/remotion` `.claude` snapshots — see `upstream.json` for SHAs and `scripts/check-upstream.sh` for drift detection.\n\nThis is a **knowledge skill**. Other skills (`/cmo-remotion`, `/video-content`, `/tiktok-slideshow`) chain into it for the rules. Don't invoke it directly to render a video — invoke it to ground yourself before you touch composition code.\n\n## On Activation\n\nRead brand files in this order. Each is a soft input — every section below works at L0 with no brand at all:\n\n1. `brand/creative-kit.md` — colors, typography, visual brand style. Drives palette, font choice, and the look of any composition you scaffold.\n2. `brand/voice-profile.md` — tone, vocabulary. Drives any visible text (titles, captions, subtitle phrasing).\n3. `brand/audience.md` — who watches. Drives pacing (tight cuts for B2C scroll feeds, longer holds for B2B explainers).\n4. `brand/positioning.md` — what the video is selling. Drives narrative beats and CTA copy.\n\nIf any file is missing or template, fall back to neutral defaults: 1920×1080 @ 30fps, system font stack, 6-second hold per beat. Tell the user once: \"Brand files thin — using neutral defaults. Run `/cmo` foundation to ground future videos.\"\n\n## When to use\n\n- User mentions Remotion, `useCurrentFrame`, `interpolate`, `spring`, `<Sequence>`, `<Composition>`, `staticFile`.\n- User wants to scaffold a programmatic React video (`npx create-video@latest`).\n- User wants HtmlInCanvas, CRT terminal, glitch, video shader, or WebGL post-processing.\n- User is debugging captions, subtitles, voiceover, audio visualization, or ffmpeg-piped Remotion work.\n- User is rendering with `npx remotion render` and hitting WebGL / GPU / fps issues.\n\nDo **not** use for: assembling a finished MP4 from existing slide PNGs (`/video-content`), inspiration-to-MP4 from a reference URL (`/cmo-video`), or TikTok slideshow chains (`/tiktok-slideshow`).\n\n## Hard Rules\n\nThese are non-negotiable. Violating them produces black frames, stuttered playback, or render failures.\n\n| Rule | Why |\n|---|---|\n| **CSS transitions / `@keyframes` are FORBIDDEN.** | Remotion renders frame-by-frame. CSS animations are time-based and will not advance during a still or video render. |\n| **Tailwind animation classes (`animate-*`) are FORBIDDEN.** | Same reason — they compile to CSS animations. Tailwind for layout/colors is fine; Tailwind for motion is broken. |\n| **Drive every motion off `useCurrentFrame()` + `interpolate()` or `spring()`.** | Frame is the only source of truth Remotion can serialize across the render worker pool. |\n| **Use `<Img>`, `<Video>`, `<Audio>` from `@remotion/media`** — never native `<img>` / `<video>` / `<audio>`. | Native elements don't participate in Remotion's frame-locking, so video frames desync from the timeline and audio drifts. |\n| **Reference public assets via `staticFile(\"path\")`** — never hardcoded `/path` or `./path`. | `staticFile` resolves correctly in Studio, in the renderer, and in deployed Lambda functions. Hardcoded paths break in Lambda. |\n| **Render-then-inspect.** | A composition that looks right in Studio can still ship broken frames. Render a still or short clip and look at it before declaring done. |\n| **One-frame sanity check before any long render.** | `npx remotion still <id> --frame=30 --scale=0.25` is ~2 seconds. Catches missing assets, font fallbacks, layout overflow, and Tailwind misconfigs before you burn 20 minutes on a 30-second render. |\n\n## New project setup\n\nWhen in an empty folder or a workspace with no existing Remotion project:\n\n```bash\nnpx create-video@latest --yes --blank --no-tailwind my-video\ncd my-video\nnpx remotion studio\n```\n\nFlags:\n- `--yes` — skip the interactive prompt.\n- `--blank` — minimal scaffold, no demo composition.\n- `--no-tailwind` — Tailwind ships with `animate-*` utilities that will tempt the next agent to use forbidden CSS animations. Skip it. Add Tailwind later only if you need its layout utilities and you're disciplined about animation.\n\nFor mktg projects, scaffold under `marketing/video/<name>/` so renders land alongside the rest of the marketing artifacts.\n\n## Rule Index — load on demand\n\nThe full rule corpus lives in `rules/`. Load only what you need for the current task — don't preload everything.\n\n### Animation core\n- [rules/timing.md](rules/timing.md) — `interpolate` ranges, Bézier easing, `spring()` configuration.\n- [rules/sequencing.md](rules/sequencing.md) — `<Sequence from>` / `durationInFrames`, layout=\"none\" for inline content.\n- [rules/transitions.md](rules/transitions.md) — `<TransitionSeries>` for scene-to-scene transitions.\n- [rules/trimming.md](rules/trimming.md) — cutting the head or tail of an animation cleanly.\n- [rules/text-animations.md](rules/text-animations.md) — typography motion patterns.\n\n### Effects\n- [rules/html-in-canvas.md](rules/html-in-canvas.md) — `<HtmlInCanvas>` for 2D/WebGL post-processing of DOM. **The user-asked feature.** See dedicated section below.\n- [rules/light-leaks.md](rules/light-leaks.md) — `@remotion/light-leaks` overlays.\n- [rules/transparent-videos.md](rules/transparent-videos.md) — alpha-channel render output.\n- [rules/lottie.md](rules/lottie.md) — embedded Lottie JSON animations.\n\n### Audio & narration\n- [rules/audio.md](rules/audio.md) — trimming, volume curves, speed, pitch.\n- [rules/voiceover.md](rules/voiceover.md) — ElevenLabs TTS into a Remotion composition.\n- [rules/sfx.md](rules/sfx.md) — sound effects, layering.\n- [rules/audio-visualization.md](rules/audio-visualization.md) — spectrum bars, waveforms, bass-reactive visuals.\n- [rules/get-audio-duration.md](rules/get-audio-duration.md) — Mediabunny audio duration.\n- [rules/silence-detection.md](rules/silence-detection.md) — auto-trim silent segments via ffmpeg.\n\n### Captions & subtitles\n- [rules/subtitles.md](rules/subtitles.md) — basic subtitle rendering.\n- [rules/display-captions.md](rules/display-captions.md) — caption styling and positioning.\n- [rules/import-srt-captions.md](rules/import-srt-captions.md) — load `.srt` files into a composition.\n- [rules/transcribe-captions.md](rules/transcribe-captions.md) — whisper-style transcription into captions.\n\n### Media handling\n- [rules/images.md](rules/images.md) — sizing, dynamic paths, dimension queries.\n- [rules/videos.md](rules/videos.md) — embedding videos with trimming, volume, speed, looping.\n- [rules/gifs.md](rules/gifs.md) — GIFs synchronized to the Remotion timeline.\n- [rules/get-video-dimensions.md](rules/get-video-dimensions.md) — Mediabunny dimensions.\n- [rules/get-video-duration.md](rules/get-video-duration.md) — Mediabunny duration.\n- [rules/ffmpeg.md](rules/ffmpeg.md) — pipeline-side video operations (encoding, format conversion, trimming).\n\n### Composition & metadata\n- [rules/compositions.md](rules/compositions.md) — stills, folders, default props, nested compositions.\n- [rules/calculate-metadata.md](rules/calculate-metadata.md) — dynamic `durationInFrames` / dimensions / props from async data.\n- [rules/parameters.md](rules/parameters.md) — Zod schemas for parametrizable compositions.\n\n### Typography\n- [rules/google-fonts.md](rules/google-fonts.md) — recommended font path. Use this first.\n- [rules/local-fonts.md](rules/local-fonts.md) — fallback when a font isn't on Google Fonts.\n- [rules/measuring-text.md](rules/measuring-text.md) — fitting text to containers, overflow detection.\n- [rules/measuring-dom-nodes.md](rules/measuring-dom-nodes.md) — measure rendered DOM dimensions.\n\n### Specialty\n- [rules/3d.md](rules/3d.md) — Three.js / React Three Fiber inside Remotion.\n- [rules/mapbox.md](rules/mapbox.md) — animated Mapbox flyovers (use static images for trivial maps).\n- [rules/tailwind.md](rules/tailwind.md) — Tailwind setup notes if you must use it. Animation classes still forbidden.\n\n## Composition shape\n\nThe canonical frame-driven fade-in. Memorize this shape — every other animation is a variation.\n\n```tsx\nimport { AbsoluteFill, Easing, interpolate, useCurrentFrame, useVideoConfig } from \"remotion\";\n\nexport const FadeIn: React.FC = () => {\n  const frame = useCurrentFrame();\n  const { fps } = useVideoConfig();\n\n  const opacity = interpolate(frame, [0, 2 * fps], [0, 1], {\n    extrapolateRight: \"clamp\",\n    extrapolateLeft: \"clamp\",\n    easing: Easing.bezier(0.16, 1, 0.3, 1),\n  });\n\n  return (\n    <AbsoluteFill style={{ justifyContent: \"center\", alignItems: \"center\" }}>\n      <h1 style={{ opacity, fontSize: 120 }}>Hello</h1>\n    </AbsoluteFill>\n  );\n};\n```\n\nWidth / height / fps / duration belong on the `<Composition>` in `src/Root.tsx`. For dynamic durations (e.g., audio-driven length), use `calculateMetadata` — see [rules/calculate-metadata.md](rules/calculate-metadata.md).\n\n## Render pipeline\n\n```bash\n# Preview interactively\nnpx remotion studio\n\n# One-frame sanity check (always do this first)\nnpx remotion still MyComposition --frame=30 --scale=0.25 --output=out/check.png\n\n# Full render\nnpx remotion render MyComposition out/video.mp4\n\n# WebGL effects (HtmlInCanvas + WebGL, shaders, Three.js)\nnpx remotion render MyComposition out/video.mp4 --gl=angle\n```\n\nSet `--gl=angle` as the default in `remotion.config.ts` once a project uses WebGL anywhere — it avoids \"blank frames in render but fine in Studio\" surprises.\n\n```ts\nimport { Config } from \"@remotion/cli/config\";\nConfig.setChromiumOpenGlRenderer(\"angle\");\n```\n\n## HtmlInCanvas — the user-asked feature\n\n`<HtmlInCanvas>` renders DOM children into a `<canvas>` so you can post-process them with the Canvas 2D API or WebGL. This is how you build CRT terminals, glitch effects, video shaders, and other \"DOM but with a filter on top\" looks.\n\n**Constraints:**\n- Chrome 149+ with `chrome://flags/#canvas-draw-element` enabled. Tell the user this once.\n- Non-Chromium machines cannot render — flag it before starting work.\n- Do NOT nest `<HtmlInCanvas>` inside another `<HtmlInCanvas>`. Remotion throws.\n- Use `--gl=angle` whenever the inner effect uses WebGL.\n\n**Working 2D blur example** (frame-driven blur radius via `onPaint`):\n\n```tsx\nimport {\n  AbsoluteFill,\n  HtmlInCanvas,\n  type HtmlInCanvasOnPaint,\n  useCurrentFrame,\n  useVideoConfig,\n} from \"remotion\";\nimport { useCallback } from \"react\";\n\nexport const Blur: React.FC = () => {\n  const frame = useCurrentFrame();\n  const { width, height, fps } = useVideoConfig();\n\n  const onPaint: HtmlInCanvasOnPaint = useCallback(\n    ({ canvas, element, elementImage }) => {\n      const ctx = canvas.getContext(\"2d\");\n      if (!ctx) throw new Error(\"Failed to acquire 2D context\");\n\n      const blurPx = 4 + 18 * (0.5 + 0.5 * Math.sin((frame / fps) * Math.PI));\n\n      ctx.reset();\n      ctx.filter = `blur(${blurPx}px)`;\n      const transform = ctx.drawElementImage(elementImage, 0, 0);\n      element.style.transform = transform.toString();\n    },\n    [frame, fps],\n  );\n\n  return (\n    <HtmlInCanvas width={width} height={height} onPaint={onPaint}>\n      <AbsoluteFill style={{ justifyContent: \"center\", alignItems: \"center\", fontSize: 120 }}>\n        <h1>Hello</h1>\n      </AbsoluteFill>\n    </HtmlInCanvas>\n  );\n};\n```\n\nFor the full WebGL pattern (texture upload via `gl.texElementImage2D`, shader programs, async multi-pass), see [rules/html-in-canvas.md](rules/html-in-canvas.md).\n\nFor a complete CRT terminal scene with scanlines, phosphor glow, and chromatic aberration, see the `/cmo-remotion` skill's `templates/CRTComposition.tsx`.\n\n## Anti-Patterns\n\n| Anti-pattern | Instead | Why |\n|---|---|---|\n| `@keyframes` or CSS `transition` | `interpolate(frame, ...)` | CSS animations are wall-clock; render workers freeze frames mid-animation and produce stutters or static stills. |\n| Tailwind `animate-pulse` / `animate-bounce` / etc. | Spring or interpolate driven by frame | Same root cause — Tailwind compiles motion utilities to CSS animations. |\n| `<img src=\"...\">` / native `<video>` / native `<audio>` | `<Img>` / `<Video>` / `<Audio>` from `@remotion/media` | Native elements don't sync to Remotion's frame clock. Video desyncs and audio drifts. |\n| Hardcoded `/logo.png` or `./assets/x.png` | `staticFile(\"logo.png\")` from `public/` | Hardcoded paths break in Lambda renders and can break in Studio depending on dev-server config. |\n| Skipping the one-frame `still` check | `npx remotion still <id> --frame=30 --scale=0.25` first | Catches missing fonts, broken paths, overflow in 2 seconds instead of 20-minute renders. |\n| Nesting `<HtmlInCanvas>` inside `<HtmlInCanvas>` | Merge effects into one outer canvas | Chrome only honors the outermost effect; Remotion throws an explicit error. |\n| WebGL effects rendered without `--gl=angle` | Add `--gl=angle` to render and `Config.setChromiumOpenGlRenderer(\"angle\")` to config | Default GL backend silently produces blank frames in headless renders; ANGLE is required for parity with Studio. |\n| Running on a non-Chromium machine for HtmlInCanvas work | Flag the constraint before starting; render on a Chrome 149+ host | Firefox / Safari engines can't enable `canvas-draw-element`; render will fail with no signal. |\n| Reading the rule index for files you don't need | Load just the rule files relevant to the current task | The rule corpus is large — preloading wastes context budget that should go to brand files and the actual composition. |\n\n## Checking for upstream updates\n\nThis skill mirrors content from `remotion-dev/skills` (primary) and `remotion-dev/remotion` `.claude` (secondary). To check for drift:\n\n```bash\n./skills/remotion-best-practices/scripts/check-upstream.sh\n```\n\nThe script compares pinned SHAs in `upstream.json` against the latest commits in both upstream repos and reports added/changed rule files. Owned by ironmint — do not edit `upstream.json` or `scripts/` from this skill.\n\n## How this composes\n\nThree sibling skills overlap. Pick the right entry point — they are not interchangeable.\n\n| Skill | Use when | Inputs | Output |\n|---|---|---|---|\n| `remotion-best-practices` | You are writing or debugging Remotion code itself. Domain knowledge only. | Composition source, rendering question | Guidance + rule pointers |\n| `/cmo-remotion` | You want a polished programmatic video built end-to-end with mktg brand context. | Brief, brand files | Scaffolded composition + render |\n| `/video-content` | You already have slide PNGs and want them assembled into an MP4 (ffmpeg or Remotion tier). | PNG slides, audio | Finished MP4 |\n| `/tiktok-slideshow` | You want the full pipeline from positioning angle to TikTok-ready video. | Positioning angle | Script → slides → video |\n\n`remotion-best-practices` is the **shared knowledge layer** under `/cmo-remotion` and `/video-content` (Remotion tier). Skills do not call it directly — they chain in the rules they need by file path.\n\n## Attribution\n\nMirrored from:\n- **Primary:** [remotion-dev/skills](https://github.com/remotion-dev/skills) — `skills/remotion/SKILL.md` and the full `skills/remotion/rules/` tree (35 files).\n- **Secondary:** [remotion-dev/remotion](https://github.com/remotion-dev/remotion) — `.claude/` patterns referenced in `references/upstream-internal/MAP.md`.\n\nSnapshot SHAs and pinned tags live in `upstream.json`. Curated and adapted via `/mktg-steal` on 2026-05-04.\n\nCredit to **@JonnyBurger** and the Remotion contributors. Upstream is MIT-licensed; see each upstream repo for the canonical license text. The mktg adaptation only changes the entry-point SKILL.md (this file) and adds provenance scaffolding — the rule corpus is mirrored verbatim.","tags":["remotion","best","practices","marketing","cli","moizibnyousaf","agent-skills","ai-agents","ai-marketing","brand-memory","brand-voice","claude-code"],"capabilities":["skill","source-moizibnyousaf","skill-remotion-best-practices","topic-agent-skills","topic-ai-agents","topic-ai-marketing","topic-brand-memory","topic-brand-voice","topic-claude-code","topic-claude-code-skills","topic-cli","topic-cmo","topic-marketing-automation","topic-marketing-cli","topic-seo"],"categories":["marketing-cli"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/MoizIbnYousaf/marketing-cli/remotion-best-practices","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add MoizIbnYousaf/marketing-cli","source_repo":"https://github.com/MoizIbnYousaf/marketing-cli","install_from":"skills.sh"}},"qualityScore":"0.459","qualityRationale":"deterministic score 0.46 from registry signals: · indexed on github topic:agent-skills · 18 github stars · SKILL.md body (15,599 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T19:05:51.876Z","embedding":null,"createdAt":"2026-05-05T07:02:34.051Z","updatedAt":"2026-05-18T19:05:51.876Z","lastSeenAt":"2026-05-18T19:05:51.876Z","tsv":"'-04':1857 '-05':1856 '/assets/x.png':1434 '/cmo':230 '/cmo-remotion':83,1351,1715,1788 '/cmo-video':320 '/logo.png':1432 '/mktg-steal':1853 '/path':452,454 '/remotion':64,1631,1832 '/remotion-dev/remotion)':1835 '/remotion-dev/skills)':1819 '/skills':59,1625,1816 '/skills/remotion-best-practices/scripts/check-upstream.sh':1639 '/tiktok-slideshow':85,325,1759 '/video-content':84,311,1737,1790 '0':1001,1004,1295,1296 '0.16':1012 '0.25':517,1075,1469 '0.3':1014 '0.5':1280,1281 '1':135,1005,1013,1015 '1080':209 '120':1027,1316 '149':1178,1556 '18':1279 '1920':208 '2':154,519,1002,1478 '20':534,1482 '2026':1855 '2d':1151,1219,1265,1274 '2d/webgl':714 '3':166 '30':515,538,1073,1467 '30fps':210 '35':1826 '4':183,1278 '6':214 'aberr':1348 'absolutefil':980,1017,1231,1309 'acquir':1273 'across':413 'activ':112 'actual':1611 'adapt':1851,1881 'add':611,1510,1892 'added/changed':1657 'advanc':365 'agent':603 'alignitem':1021,1313 'alongsid':636 'alpha':736 'alpha-channel':735 'alreadi':1739 'alway':1064 'angl':1097,1100,1129,1211,1509,1512,1517,1530,1767,1774 'anim':27,45,357,373,375,384,596,608,626,668,703,745,936,955,974,1370,1381,1390,1393,1411 'animate-bounc':1392 'animate-puls':1389 'anoth':1206 'anti':1356,1359 'anti-pattern':1355,1358 'anywher':1111 'api':1152 'artifact':642 'ask':723,1134 'assembl':303,1746 'asset':446,523 'async':882,1329 'attribut':1809 'audio':278,442,746,780,1043,1429,1756 'audio-driven':1042 'auto':785 'auto-trim':784 'avoid':1113 'b2b':181 'b2c':175 'back':204 'backend':1522 'bar':771 'base':361 'bash':557,1053,1638 'basic':795 'bass':774 'bass-react':773 'beat':192,218 'belong':1033 'best':3,8,37,1695,1780 'black':336 'blank':564,584,1114,1525 'blur':1220,1225,1245,1288 'blurpx':1277,1289 'bounc':1394 'brand':114,132,140,223,1607,1729,1732 'brand/audience.md':167 'brand/creative-kit.md':136 'brand/positioning.md':184 'brand/voice-profile.md':155 'break':470,1441,1447 'brief':1731 'broken':394,487,1474 'budget':1602 'build':1159 'built':1722 'burn':533 'bézier':674 'calcu':35 'calculatemetadata':1047 'call':1796 'cannot':1195 'canon':962,1876 'canva':1150,1182,1259,1492,1565 'canvas-draw-el':1181,1564 'canvas.getcontext':1264 'caption':163,275,791,800,819 'catch':521,1471 'caus':1404 'cd':571 'center':1020,1022,1312,1314 'chain':86,324,1800 'chang':1883 'channel':737 'check':506,1063,1462,1613,1635 'children':1138 'choic':145 'chromat':1347 'chrome':1177,1493,1555 'chromium':1193,1542 'clamp':1007,1009 'class':374,956 'claud':65,1632,1836 'clean':704 'clip':494 'clock':1374,1425 'code':24,110,1703 'color':137 'commit':1650 'compar':1642 'compil':381,1406 'complet':1338 'compos':1674 'composit':25,109,151,478,589,762,811,865,874,890,959,1612,1708,1735 'config':1125,1455,1519 'config.setchromiumopenglrenderer':1128,1516 'configur':677 'const':988,991,994,997,1244,1247,1250,1255,1262,1276,1291 'constraint':1176,1549 'contain':916 'content':685,1620 'context':1275,1601,1730 'contributor':1864 'convers':863 'copi':195 'core':669 'corpus':651,1596,1897 'correct':457 'creat':256,560 'create-video':255,559 'credit':1858 'crt':262,1160,1339 'css':345,356,383,607,1365,1369,1410 'cta':194 'ctx':1263,1267 'ctx.drawelementimage':1293 'ctx.filter':1287 'ctx.reset':1286 'curat':1849 'current':662,1592 'curv':752 'cut':173,696 'data':883 'debug':20,274,1701 'declar':500 'dedic':726 'default':207,228,871,1103,1520 'demand':647 'demo':588 'depend':1450 'deploy':465 'desync':437,1427 'detect':75,918 'dev':58,63,1453,1624,1630,1815,1831 'dev-serv':1452 'dimens':827,849,879,924 'direct':96,1798 'disciplin':624 'dom':719,923,1137,1168 'domain':40,1705 'domain-specif':39 'done':501 'draw':1183,1566 'drift':74,443,1430,1637 'drive':142,158,170,190,395 'driven':965,1044,1224,1399 'durat':781,853,1032,1040 'durationinfram':680,878 'dynam':825,877,1039 'e.g':1041 'eas':675,981,1010 'easing.bezier':1011 'edit':1665 'effect':710,766,1086,1163,1215,1488,1498,1505 'element':424,1184,1260,1417,1567 'element.style.transform':1297 'elementimag':1261,1294 'elevenlab':757 'embed':742,831 'empti':547 'enabl':1185,1563 'encod':861 'end':1724,1726 'end-to-end':1723 'engin':1560 'entri':1682,1886 'entry-point':1885 'error':1270,1503 'etc':1395 'everi':124,396,972 'everyth':667 'exampl':1221 'exist':308,554 'explain':182 'explicit':1502 'export':987,1243 'extrapolateleft':1008 'extrapolateright':1006 'fade':967 'fade-in':966 'fadein':989 'fail':1271,1570 'failur':342 'fall':203 'fallback':525,902 'featur':724,1135 'feed':177 'ffmpeg':282,790,1750 'ffmpeg-pip':281 'fiber':931 'file':115,198,224,808,1579,1588,1608,1659,1733,1807,1827,1890 'filter':1172 'fine':389,1119 'finish':305,1757 'firefox':1558 'first':899,1067,1470 'fit':913 'flag':578,1180,1197,1547 'flyover':938 'folder':548,870 'font':144,212,524,895,905,910,1473 'fontsiz':1026,1315 'forbidden':349,377,606,958 'format':862 'foundat':231 'fps':297,995,1003,1031,1253,1284,1300 'frame':337,353,355,403,432,436,488,504,514,964,992,1000,1061,1072,1115,1223,1248,1283,1299,1368,1378,1401,1424,1460,1466,1526 'frame-by-fram':352 'frame-driven':963,1222 'frame-lock':431 'freez':1377 'full':649,1078,1320,1763,1823 'function':467 'futur':234 'gif':840 'github.com':1818,1834 'github.com/remotion-dev/remotion)':1833 'github.com/remotion-dev/skills)':1817 'gl':1096,1099,1210,1508,1511,1521 'gl.texelementimage2d':1326 'glitch':264,1162 'glow':1345 'go':1605 'googl':909 'gpu':296 'ground':104,233 'guidanc':1712 'h1':1023 'handl':821 'hard':326 'hardcod':451,468,1431,1439 'head':698 'headless':1528 'height':1030,1252,1305,1306 'hello':1028,1317 'hit':294 'hold':179,216 'honor':1495 'host':1557 'htmlincanva':261,1087,1130,1232,1302,1545 'htmlincanvasonpaint':1234,1257 'imag':941 'import':979,1124,1230,1239 'index':644,1577 'inlin':684 'inner':1214 'input':123,1691 'insid':932,1205,1486 'inspect':476 'inspir':313 'inspiration-to-mp4':312 'instead':1361,1480 'interact':582,1055 'interchang':1687 'interpol':28,243,400,672,982,999,1367,1398 'invok':94,101 'ironmint':1662 'isn':906 'issu':298 'jonnyburg':1860 'json':744 'justifycont':1019,1311 'keyfram':347,1363 'knowledg':42,79,1706,1785 'l0':129 'lambda':466,472,1443 'land':635 'larg':1598 'later':613 'latest':258,562,1649 'layer':767,1786 'layout':526,619,681 'layout/colors':387 'length':1045 'licens':1869,1877 'live':652,1846 'load':645,655,806,1584 'lock':433 'logo.png':1436 'long':509 'longer':178 'look':148,480,496,1175 'loop':837 'lotti':743 'machin':1194,1543 'map':944 'mapbox':937 'market':641 'marketing/video':632 'math.pi':1285 'math.sin':1282 'measur':921 'media':820 'mediabunni':779,848,852 'memor':969 'mention':240 'merg':1487 'metadata':866 'mid':1380 'mid-anim':1379 'minim':585 'minut':535,1483 'mirror':52,1619,1810,1899 'misconfig':530 'miss':200,522,1472 'mit':1868 'mit-licens':1867 'mktg':628,1728,1880 'motion':392,397,708,1407 'mp4':306,315,1749,1758 'multi':1331 'multi-pass':1330 'must':952 'my-video':568,572 'mycomposit':1071,1083,1094 'narrat':191,747 'nativ':422,423,1412,1413,1416 'need':617,659,1583,1805 'negoti':332 'nest':873,1204,1485 'neutral':206,227 'never':421,450 'new':541,1269 'next':602 'no-tailwind':565,590 'non':331,1192,1541 'non-chromium':1191,1540 'non-negoti':330 'none':682 'note':949 'npx':254,290,511,558,575,1056,1068,1080,1091,1463 'one':503,1060,1459,1490 'one-fram':502,1059,1458 'onpaint':1228,1256,1307,1308 'opac':998,1025 'oper':860 'order':118 'out/check.png':1077 'out/video.mp4':1084,1095 'outer':1491 'outermost':1497 'output':739,1076,1692 'overflow':527,917,1476 'overlap':1678 'overlay':732 'own':1660 'pace':171 'palett':143 'parametriz':889 'pariti':1534 'particip':427 'pass':1332 'path':449,469,826,896,1440,1475,1808 'pattern':709,1322,1357,1360,1837 'per':217 'phosphor':1344 'phrase':165 'pick':1679 'pin':1643,1844 'pipe':283 'pipelin':857,1052,1764 'pipeline-sid':856 'pitch':754 'playback':339 'png':1754 'pngs':310,1742 'point':1683,1887 'pointer':1714 'polish':1719 'pool':417 'posit':803,1766,1773 'post':270,716,1145 'post-process':269,715,1144 'practic':4,9,38,1696,1781 'preload':666,1599 'preview':1054 'primari':1626,1812 'process':271,717,1146 'produc':335,1383,1524 'program':1328 'programmat':5,251,1720 'project':542,556,629,1108 'prompt':583 'prop':872,880 'proven':1893 'public':445,1438 'puls':1391 'px':1290 'queri':828 'question':1711 'radius':1226 'rang':673 're':623 'react':6,51,252,929,1242 'react.fc':990,1246 'reactiv':775 'read':113,1574 'readi':1771 'reason':379 'recommend':894 'refer':318,444 'referenc':1838 'references/upstream-internal/map.md':1840 'relev':1589 'remot':2,11,23,36,48,57,62,241,284,291,350,410,429,512,555,576,761,844,933,986,1057,1069,1081,1092,1207,1238,1422,1464,1499,1623,1629,1694,1702,1752,1779,1791,1814,1830,1863 'remotion-best-practic':1,1693,1778 'remotion-dev':56,61,1622,1628,1813,1829 'remotion.config.ts':1105 'remotion/cli/config':1127 'remotion/light-leaks':731 'remotion/media':33,420,1415 'render':22,47,98,288,292,341,351,371,415,462,474,489,510,540,634,738,797,922,1051,1079,1082,1093,1117,1136,1196,1375,1444,1484,1506,1514,1529,1552,1568,1710,1736 'render-then-inspect':473 'repo':1654,1873 'report':1656 'requir':1532 'resolv':456 'rest':638 'return':1016,1301 'right':481,1681 'root':1403 'rule':91,327,343,643,650,654,1576,1587,1595,1658,1713,1803,1896 'rules/3d.md':926,927 'rules/audio-visualization.md':768,769 'rules/audio.md':748,749 'rules/calculate-metadata.md':875,876,1049,1050 'rules/compositions.md':867,868 'rules/display-captions.md':798,799 'rules/ffmpeg.md':854,855 'rules/get-audio-duration.md':777,778 'rules/get-video-dimensions.md':846,847 'rules/get-video-duration.md':850,851 'rules/gifs.md':838,839 'rules/google-fonts.md':892,893 'rules/html-in-canvas.md':711,712,1334,1335 'rules/images.md':822,823 'rules/import-srt-captions.md':804,805 'rules/light-leaks.md':729,730 'rules/local-fonts.md':900,901 'rules/lottie.md':740,741 'rules/mapbox.md':934,935 'rules/measuring-dom-nodes.md':919,920 'rules/measuring-text.md':911,912 'rules/parameters.md':884,885 'rules/sequencing.md':678,679 'rules/sfx.md':763,764 'rules/silence-detection.md':782,783 'rules/subtitles.md':793,794 'rules/tailwind.md':945,946 'rules/text-animations.md':705,706 'rules/timing.md':670,671 'rules/transcribe-captions.md':812,813 'rules/transitions.md':686,687 'rules/transparent-videos.md':733,734 'rules/trimming.md':694,695 'rules/videos.md':829,830 'rules/voiceover.md':755,756 'run':229,1537 'safari':1559 'saniti':505,1062 'scaffold':153,249,586,630,1734,1894 'scale':516,1074,1468 'scanlin':1343 'scene':690,692,1341 'scene-to-scen':689 'schema':887 'script':1641,1668,1775 'scripts/check-upstream.sh':72 'scroll':176 'second':215,520,539,1479 'secondari':1633,1828 'section':125,727 'see':67,725,1048,1333,1349,1870 'segment':788 'sell':189 'sequenc':30 'serial':412 'server':1454 'set':1098 'setup':543,948 'shader':266,1089,1165,1327 'shape':960,971 'share':1784 'shas':70,1644,1842 'ship':486,594 'short':493 'sibl':1676 'side':858 'signal':1573 'silent':787,1523 'size':824 'skill':14,80,82,1352,1618,1671,1677,1688,1793 'skill-remotion-best-practices' 'skill.md':1888 'skills/remotion/rules':1824 'skills/remotion/skill.md':1820 'skip':580,609,1456 'slide':309,1741,1755,1776 'slideshow':323 'snapshot':66,1841 'soft':122 'sound':765 'sourc':407,1709 'source-moizibnyousaf' 'specialti':925 'specif':41 'spectrum':770 'speed':753,836 'spring':29,244,402,676,1396 'src/root.tsx':1037 'srt':807 'stack':213 'start':1200,1551 'static':940,1386 'staticfil':34,245,448,455,1435 'still':368,485,491,513,869,957,1070,1387,1461,1465 'studio':459,483,577,1058,1121,1449,1536 'stutter':338,1384 'style':141,801,816,1018,1024,1310 'subtitl':164,276,792,796 'surpris':1122 'sync':1420 'synchron':841 'system':211 'tag':1845 'tail':700 'tailwind':372,385,390,529,567,592,593,612,947,1388,1405 'task':663,1593 'tell':219,1186 'templat':202 'templates/crtcomposition.tsx':1354 'tempt':600 'termin':263,1161,1340 'text':161,914,1878 'textur':1323 'thin':225 'three':930,1675 'three.js':928,1090 'throw':1208,1268,1500 'tier':1753,1792 'tight':172 'tiktok':322,1770 'tiktok-readi':1769 'time':31,360 'time-bas':359 'timelin':440,845 'titl':162 'tone':156 'top':1174 'topic-agent-skills' 'topic-ai-agents' 'topic-ai-marketing' 'topic-brand-memory' 'topic-brand-voice' 'topic-claude-code' 'topic-claude-code-skills' 'topic-cli' 'topic-cmo' 'topic-marketing-automation' 'topic-marketing-cli' 'topic-seo' 'touch':108 'transcript':817 'transform':1292 'transform.tostring':1298 'transit':346,693,1366 'tree':1825 'trim':750,786,834,864 'trivial':943 'truth':409 'ts':1123 'tsx':978,1229 'tts':758 'type':1233 'typographi':138,707,891 'updat':1616 'upload':1324 'upstream':55,1615,1653,1865,1872 'upstream.json':68,1646,1666,1848 'url':319 'use':12,226,238,301,418,605,897,939,953,1046,1109,1209,1216,1689 'usecallback':1240,1258 'usecurrentfram':26,242,399,983,993,1235,1249 'user':17,221,239,246,259,272,286,722,1133,1188 'user-ask':721,1132 'usevideoconfig':984,996,1236,1254 'util':597,620,1408 'variat':977 'verbatim':1900 'via':447,789,1227,1325,1852 'video':7,49,100,187,235,253,257,265,370,435,561,570,574,832,859,1164,1426,1721,1772,1777 'violat':333 'visibl':160 'visual':139,279,776 'vocabulari':157 'voiceov':277 'volum':751,835 'wall':1373 'wall-clock':1372 'want':247,260,1717,1744,1761 'wast':1600 'watch':169 'waveform':772 'webgl':268,295,1085,1088,1110,1154,1217,1321,1504 'whenev':15,1212 'whisper':815 'whisper-styl':814 'width':1029,1251,1303,1304 'without':1507 'work':127,285,1201,1218,1546 'worker':416,1376 'workspac':551 'write':19,44,1699 'yes':563,579 'zod':886","prices":[{"id":"721a2ffa-574a-4b73-bea8-6a628e82c470","listingId":"74e7359f-9a97-49b6-b3a8-6fd4d1b1ecc0","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"MoizIbnYousaf","category":"marketing-cli","install_from":"skills.sh"},"createdAt":"2026-05-05T07:02:34.051Z"}],"sources":[{"listingId":"74e7359f-9a97-49b6-b3a8-6fd4d1b1ecc0","source":"github","sourceId":"MoizIbnYousaf/marketing-cli/remotion-best-practices","sourceUrl":"https://github.com/MoizIbnYousaf/marketing-cli/tree/main/skills/remotion-best-practices","isPrimary":false,"firstSeenAt":"2026-05-05T07:02:34.051Z","lastSeenAt":"2026-05-18T19:05:51.876Z"}],"details":{"listingId":"74e7359f-9a97-49b6-b3a8-6fd4d1b1ecc0","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"MoizIbnYousaf","slug":"remotion-best-practices","github":{"repo":"MoizIbnYousaf/marketing-cli","stars":18,"topics":["agent-skills","ai-agents","ai-marketing","brand-memory","brand-voice","claude-code","claude-code-skills","cli","cmo","marketing-automation","marketing-cli","seo","skills-sh","typescript"],"license":"mit","html_url":"https://github.com/MoizIbnYousaf/marketing-cli","pushed_at":"2026-05-13T21:06:05Z","description":"Agent-native marketing cli: 51 skills, 5 research agents, brand memory that compounds, plus a local Studio dashboard (beta). single agent-native cli, then /cmo in ur coding agent..","skill_md_sha":"6b7290210004d7ff818b46f728abdbc480a28d34","skill_md_path":"skills/remotion-best-practices/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/MoizIbnYousaf/marketing-cli/tree/main/skills/remotion-best-practices"},"layout":"multi","source":"github","category":"marketing-cli","frontmatter":{"name":"remotion-best-practices","description":"Programmatic React video best practices for Remotion. Use this skill whenever the user is writing, debugging, or rendering Remotion code — compositions, useCurrentFrame animations, interpolate, spring, Sequence timing, <Img>/<Video>/<Audio> from @remotion/media, staticFile, calculateMetadata, the Studio preview, `npx remotion render`, captions, subtitles, voiceover, audio visualization, ffmpeg, transitions, light leaks, transparent video, Lottie, 3D scenes, Mapbox flyovers. Triggers especially on HtmlInCanvas / \"html in canvas\" requests, CRT terminal effects, glitch effects, video shaders, WebGL video, and any request to scaffold a new programmatic React video. Do NOT trigger for finished MP4 ad assembly from existing slides (that is `/video-content`) or for the inspiration-to-MP4 reference-video pipeline (that is `/cmo-video`)."},"skills_sh_url":"https://skills.sh/MoizIbnYousaf/marketing-cli/remotion-best-practices"},"updatedAt":"2026-05-18T19:05:51.876Z"}}