{"id":"36089ff0-ad14-44fd-b8b7-87074833c27d","slug":"remotion-gsap","kind":"skill","name":"remotion-gsap","summary":"Deterministic, frame-driven GSAP timelines for Remotion","owner":"Fats403","repoUrl":"https://github.com/Fats403/remotion-gsap","license":"MIT","licenseTier":"permissive","trust":"community","stars":2,"match":null,"fewStars":true,"format":"skill","createdAt":"2026-08-14T00:06:22.000Z","addedAt":"2026-10-22T01:40:04.021Z","logoUrl":"https://avatars.githubusercontent.com/u/30492327?u=57a6f5993e37d3de5b0a53a687235d970c8aaef5&v=4","linkOnly":false,"collection":null,"skillPath":null,"categories":["design-media"],"tags":["animation","gsap","motion-graphics","react","remotion","video"],"runtime":"binary","local":true,"cloudCapable":false,"cloudCapability":"unknown","cloudReadyOnPlatform":false,"needsApiKey":false,"reviewed":false,"syncedAt":"2026-10-26T21:33:37.837Z","sample":false,"url":"https://conduits.dev/tools/remotion-gsap","language":"TypeScript","transports":["stdio"],"install":{},"requirements":{"env":[],"upstreamMayCharge":false},"tools":null,"readme":"# remotion-gsap\n\nDeterministic GSAP timelines for Remotion.\n\n![Kinetic type choreographed with one GSAP timeline](https://raw.githubusercontent.com/Fats403/remotion-gsap/main/assets/kinetic.gif)\n\n## The problem\n\nRemotion makes frame-based animation predictable. Complex choreography can still become difficult to maintain once a scene has overlapping entrances, labels, staggers, transforms, and transitions.\n\nGSAP has a strong timeline API for that work. `remotion-gsap` connects it to Remotion without giving up deterministic rendering.\n\nRemotion remains the clock. GSAP describes the motion.\n\n## Why not just play() the timeline?\n\nGSAP normally advances on its own requestAnimationFrame ticker. That looks right in Studio preview and breaks in `renderMedia()`, where frames are captured headlessly, concurrently, and out of order. A ticker-driven timeline produces different pixels on different runs.\n\nThis hook never lets the ticker run. It seeks a paused timeline, so every frame is a pure function of the frame number, no matter what order frames render in or how many render at once.\n\n## Install\n\n```sh\nnpm install remotion-gsap gsap\n```\n\nRequires GSAP 3.12+, React 18 or 19, and Remotion 4.\n\n## Example\n\n```tsx\nimport {AbsoluteFill} from 'remotion';\nimport {useGsapTimeline} from 'remotion-gsap';\n\nexport const Scene = () => {\n  const scope = useGsapTimeline<HTMLDivElement>(({timeline, selector}) => {\n    timeline\n      .from(selector('[data-title]'), {\n        yPercent: 120,\n        opacity: 0,\n        duration: 0.8,\n        ease: 'power4.out',\n      })\n      .from(\n        selector('[data-card]'),\n        {\n          y: 80,\n          opacity: 0,\n          stagger: 0.08,\n          duration: 0.6,\n          ease: 'power3.out',\n        },\n        '-=0.3',\n      );\n  });\n\n  return (\n    <AbsoluteFill ref={scope}>\n      <h1 data-title>Build better timelines</h1>\n      <div data-card>One</div>\n      <div data-card>Two</div>\n    </AbsoluteFill>\n  );\n};\n```\n\nThe hook creates one scoped, paused GSAP timeline. On each Remotion frame, it seeks the timeline to `frame / fps`. Playback, manual seeking (`seek`, `time`, `totalTime`, `progress`, `tweenTo`, and related methods), pause-state mutation, and cleanup are package-owned and rejected inside builders.\n\nUse GSAP labels, position parameters, staggers, keyframes, repeats, yoyo, CSS transforms, SVG attributes, and nested timelines as usual.\n\n## Demos\n\nEach of these is one `useGsapTimeline` builder, rendered with the standard Remotion renderer.\n\n![Dashboard choreography](https://raw.githubusercontent.com/Fats403/remotion-gsap/main/assets/dashboard.gif)\n\nStaggered card entrances and SVG chart draw-ins, sequenced with labels and position parameters.\n\n![Scene transition](https://raw.githubusercontent.com/Fats403/remotion-gsap/main/assets/transition.gif)\n\nScene-to-scene clip-path wipes and staggered reveals, with repeat and yoyo accents.\n\n## Dynamic values\n\nPass values used to build the timeline as dependencies:\n\n```tsx\nconst scope = useGsapTimeline<HTMLDivElement>(\n  ({timeline, selector}) => {\n    timeline.to(selector('[data-card]'), {x: distance, duration: 1});\n  },\n  {dependencies: [distance]},\n);\n```\n\n## Rules\n\n- Let Remotion own time, sequences, audio, video, captions, and composition duration.\n- Use the provided selector or direct refs. Avoid global selectors.\n- Keep timeline builders synchronous.\n- Do not call GSAP playback methods or start the GSAP ticker.\n- Do not use timeline callbacks for render-time side effects.\n- Keep React and GSAP from writing the same animated inline property.\n- Treat GSAP plugins as unsupported until they have renderer parity tests.\n\nThe adapter rejects playback, asynchronous builders, and timeline callbacks that can make rendering order-dependent.\n\n## Agent skill\n\nThe package includes an agent skill at [`SKILL.md`](./SKILL.md).\n\nGive the skill to your coding agent when generating Remotion compositions. It covers the adapter API, safe GSAP patterns, and common determinism pitfalls.\n\n```sh\nnpx skills add Fats403/remotion-gsap\n```\n\n## Tested behavior\n\n- Direct, sequential, backward, and repeated frame access\n- Serial and concurrent renderer execution\n- React 18 and 19\n- Nested and overlapping Remotion sequences\n- HTML and SVG scope roots\n- 24, 30, and 60 fps compositions\n- Packed npm consumer imports and types\n\n## License\n\nMIT. This package is unofficial and is not affiliated with Remotion or GreenSock.\n"}