
Gsap React
Implement GSAP timelines in React with useGSAP, scoped refs, cleanup, and dependency-safe animation patterns.
Overview
GSAP React is an agent skill for the Build phase that implements GSAP animations in React components with useGSAP, refs, and cleanup.
Install
npx skills add https://github.com/bbeierle12/skill-mcp-claude --skill gsap-reactWhat is this skill?
- useGSAP hook with scope ref to limit DOM queries inside components
- Cleanup and context patterns to avoid leaked timelines on unmount
- Dependency-driven animations when props like isOpen change
- npm install gsap and @gsap/react quick-start snippets
- Reusable animation hook patterns for staggered and drawer-style motion
Adoption & trust: 655 installs on skills.sh; 8 GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
You want GSAP motion in React but keep fighting useEffect leaks, unscoped selectors, and timelines that break when props change.
Who is it for?
Indie frontend devs adding marketing motion, micro-interactions, or layout transitions in React or Next-style apps.
Skip if: Non-React frameworks, CSS-only animation needs, or backend/data pipelines with no UI layer.
When should I use this skill?
Implementing GSAP animations in React components, handling component lifecycle, or building reusable animation hooks.
What do I get? / Deliverables
Components use scoped useGSAP blocks with correct cleanup and dependency handling so animations stay maintainable across rerenders.
- React components using scoped useGSAP patterns
- Reusable animation hooks with documented dependencies
Recommended Skills
Journey fit
Animation integration is frontend product work during implementation, not distribution or infra operations. The skill centers React component lifecycle, hooks, and scoped selectors—core UI build concerns.
How it compares
React lifecycle patterns for GSAP—not a general design system or Framer Motion migration guide.
Common Questions / FAQ
Who is gsap-react for?
Solo builders and frontend-focused agents implementing GSAP in React SPAs or Next.js apps who need hook-scoped, cleanup-safe animation code.
When should I use gsap-react?
Use it during Build frontend whenever you add timelines, staggers, or prop-driven motion inside React components—not for Ship perf audits unless animations cause jank you are fixing in code.
Is gsap-react safe to install?
It is documentation and code patterns only; review the Security Audits panel on this Prism page for the hosting repo before install.
SKILL.md
READMESKILL.md - Gsap React
# GSAP React Integration React-specific patterns for GSAP animations. ## Quick Start ```bash npm install gsap @gsap/react ``` ```tsx import { useGSAP } from '@gsap/react'; import gsap from 'gsap'; function Component() { const containerRef = useRef(null); useGSAP(() => { gsap.to('.box', { x: 200, duration: 1 }); }, { scope: containerRef }); return ( <div ref={containerRef}> <div className="box">Animated</div> </div> ); } ``` ## useGSAP Hook ### Basic Usage ```tsx import { useGSAP } from '@gsap/react'; import gsap from 'gsap'; function AnimatedComponent() { const container = useRef(null); useGSAP(() => { // All GSAP animations here gsap.from('.item', { opacity: 0, y: 50, stagger: 0.1 }); }, { scope: container }); // Scope limits selector queries return ( <div ref={container}> <div className="item">Item 1</div> <div className="item">Item 2</div> <div className="item">Item 3</div> </div> ); } ``` ### With Dependencies ```tsx function AnimatedComponent({ isOpen }) { const container = useRef(null); useGSAP(() => { gsap.to('.drawer', { height: isOpen ? 'auto' : 0, duration: 0.3 }); }, { scope: container, dependencies: [isOpen] }); return ( <div ref={container}> <div className="drawer">Content</div> </div> ); } ``` ### Returning Context ```tsx function Component() { const container = useRef(null); const { context, contextSafe } = useGSAP(() => { gsap.to('.box', { x: 200 }); }, { scope: container }); // Use contextSafe for event handlers const handleClick = contextSafe(() => { gsap.to('.box', { rotation: 360 }); }); return ( <div ref={container}> <div className="box" onClick={handleClick}>Click me</div> </div> ); } ``` ## Ref Patterns ### Single Element Ref ```tsx function SingleElement() { const boxRef = useRef(null); useGSAP(() => { gsap.to(boxRef.current, { x: 200, rotation: 360, duration: 1 }); }); return <div ref={boxRef}>Box</div>; } ``` ### Multiple Element Refs ```tsx function MultipleElements() { const itemsRef = useRef([]); useGSAP(() => { gsap.from(itemsRef.current, { opacity: 0, y: 30, stagger: 0.1 }); }); return ( <div> {[1, 2, 3].map((item, i) => ( <div key={item} ref={el => itemsRef.current[i] = el} > Item {item} </div> ))} </div> ); } ``` ### Dynamic Refs ```tsx function DynamicList({ items }) { const itemsRef = useRef(new Map()); useGSAP(() => { gsap.from(Array.from(itemsRef.current.values()), { opacity: 0, y: 20, stagger: 0.05 }); }, { dependencies: [items.length] }); return ( <div> {items.map(item => ( <div key={item.id} ref={el => { if (el) itemsRef.current.set(item.id, el); else itemsRef.current.delete(item.id); }} > {item.name} </div> ))} </div> ); } ``` ## Context and Cleanup ### Automatic Cleanup ```tsx // useGSAP automatically cleans up animations on unmount function Component() { useGSAP(() => { // This timeline is automatically killed on unmount gsap.timeline() .to('.a', { x: 100 }) .to('.b', { x: 100 }); }); } ``` ### Manual Context (Without useGSAP) ```tsx import gsap from 'gsap'; function Component() { useEffect(() => { const ctx = gsap.context(() => { gsap.to('.box', { x: 200 }); gsap.to('.circle', { rotation: 360 }); }); return () => ctx.revert(); // Cleanup }, []); } ``` ### Scoped Cont