Engineering GSAP Animations
Overview
Implement GSAP as a scoped, interruptible subsystem. Let product direction choose the effect; let this skill own API correctness, React lifecycle, plugin behavior, cleanup, and verification.
REQUIRED ROUTING: Use craft-premium-motion first when the technology or motion direction is still undecided. Use optimizing-frontend-motion-performance when runtime profiling or long-session degradation is the main problem.
Workflow
- Inspect the installed
gsap and @gsap/react versions, existing animation engines, Client Component boundaries, DOM ownership, fonts, media, scroller, and reduced-motion policy.
- Assign one animation owner per property and node. Put Motion state/layout effects on a child wrapper when GSAP owns a parent transform.
- Select the smallest GSAP surface: tween, timeline, ScrollTrigger, or a specific plugin.
- Implement inside a scoped
useGSAP() context. Register only used plugins, make delayed callbacks context-safe, and rebuild measurement-dependent effects when their inputs change.
- Provide a non-pinned, readable reduced-motion state. Treat mobile/coarse-pointer behavior as a deliberate variant.
- Verify production behavior through resize, font/media load, route changes, Fast Refresh, repeated mount/unmount, rapid scrolling, and preference changes.
Reference routing
| Need |
Read |
| Tweens, eases, timelines, labels, positions |
core-and-timelines.md |
React 19, Next.js App Router, useGSAP, SSR |
react-nextjs.md |
| ScrollTrigger, pin, scrub, SplitText and plugins |
scrolltrigger-and-plugins.md |
FPS, will-change, reduced motion, cleanup |
performance-accessibility.md |
Implementation contract
- Prefer refs or selectors scoped to the component root.
- Use timelines for choreography; do not chain unrelated delays.
- Use function-based measurement plus
invalidateOnRefresh when geometry can change.
- Choose one SplitText lifecycle: return the animation from
onSplit when using autoSplit, or rebuild the entire dependent timeline after a manual re-split. Never let an external timeline keep stale character nodes.
- Revert SplitText and GSAP contexts; kill observers/listeners created outside the context.
- Preserve the project's package manager and compatible versions. Add or upgrade GSAP only when the requested API is missing or the project has an evidenced compatibility problem; never replace a working version with
latest by default.
- Confirm current plugin imports and licensing from official GSAP documentation before changing dependencies.
Common mistakes
- Animating the same transform with Motion and GSAP.
- Creating ScrollTrigger before fonts, images, or layout settle.
- Using permanent
will-change across many elements.
- Calling
ScrollTrigger.refresh() repeatedly without coalescing layout changes.
- Treating build success as proof that pinning, cleanup, and reduced motion work.
Technical basis: official GreenSock GSAP skills, adapted for this stack.
1---2name: engineering-gsap-animations3description: Use when GSAP has been selected for React or Next.js animation, especially timelines, ScrollTrigger, pinning, scrub, SplitText, Flip, SVG, responsive animation, plugin lifecycle, cleanup, or animation-related integration bugs.4---56# Engineering GSAP Animations78## Overview910Implement GSAP as a scoped, interruptible subsystem. Let product direction choose the effect; let this skill own API correctness, React lifecycle, plugin behavior, cleanup, and verification.1112**REQUIRED ROUTING:** Use `craft-premium-motion` first when the technology or motion direction is still undecided. Use `optimizing-frontend-motion-performance` when runtime profiling or long-session degradation is the main problem.1314## Workflow15161. Inspect the installed `gsap` and `@gsap/react` versions, existing animation engines, Client Component boundaries, DOM ownership, fonts, media, scroller, and reduced-motion policy.172. Assign one animation owner per property and node. Put Motion state/layout effects on a child wrapper when GSAP owns a parent transform.183. Select the smallest GSAP surface: tween, timeline, ScrollTrigger, or a specific plugin.194. Implement inside a scoped `useGSAP()` context. Register only used plugins, make delayed callbacks context-safe, and rebuild measurement-dependent effects when their inputs change.205. Provide a non-pinned, readable reduced-motion state. Treat mobile/coarse-pointer behavior as a deliberate variant.216. Verify production behavior through resize, font/media load, route changes, Fast Refresh, repeated mount/unmount, rapid scrolling, and preference changes.2223## Reference routing2425| Need | Read |26|---|---|27| Tweens, eases, timelines, labels, positions | [core-and-timelines.md](references/core-and-timelines.md) |28| React 19, Next.js App Router, `useGSAP`, SSR | [react-nextjs.md](references/react-nextjs.md) |29| ScrollTrigger, pin, scrub, SplitText and plugins | [scrolltrigger-and-plugins.md](references/scrolltrigger-and-plugins.md) |30| FPS, `will-change`, reduced motion, cleanup | [performance-accessibility.md](references/performance-accessibility.md) |3132## Implementation contract3334- Prefer refs or selectors scoped to the component root.35- Use timelines for choreography; do not chain unrelated delays.36- Use function-based measurement plus `invalidateOnRefresh` when geometry can change.37- Choose one SplitText lifecycle: return the animation from `onSplit` when using `autoSplit`, or rebuild the entire dependent timeline after a manual re-split. Never let an external timeline keep stale character nodes.38- Revert SplitText and GSAP contexts; kill observers/listeners created outside the context.39- Preserve the project's package manager and compatible versions. Add or upgrade GSAP only when the requested API is missing or the project has an evidenced compatibility problem; never replace a working version with `latest` by default.40- Confirm current plugin imports and licensing from official GSAP documentation before changing dependencies.4142## Common mistakes4344- Animating the same transform with Motion and GSAP.45- Creating ScrollTrigger before fonts, images, or layout settle.46- Using permanent `will-change` across many elements.47- Calling `ScrollTrigger.refresh()` repeatedly without coalescing layout changes.48- Treating build success as proof that pinning, cleanup, and reduced motion work.4950Technical basis: official [GreenSock GSAP skills](https://github.com/greensock/gsap-skills), adapted for this stack.