useGSAP
useGSAP is the official React hook from `@gsap/react` that scopes GSAP animations to a component and cleans them up automatically on unmount. It replaces `useEffect` for GSAP work, handles StrictMode's double-invocation correctly, and exposes `contextSafe` for wrapping event handlers that create tweens.
Updated June 1, 2026
How useGSAP works
useGSAP wraps gsap.context() under the hood. Pass a callback that creates your tweens and timelines; the hook records everything inside that context and reverts it on unmount. Any element you query inside the callback is scoped to the scope ref you pass in, so animations stay local to the component instance.
The second argument can also be a dependencies array. The hook re-runs the callback (after reverting the previous context) whenever a dependency changes, which is how you wire props or state into the animation.
Use contextSafe for event handlers
Tweens created outside the initial callback - inside an onClick, a mouseenter handler, an effect that runs later - won't be tracked by the context and won't be reverted on unmount. Wrap those handlers in contextSafe so the same auto-cleanup applies.
Use useGSAP for
- Any GSAP animation inside a React component (the canonical pattern)
- Scroll-driven reveals where ScrollTrigger should auto-clean on unmount
- Hover and click interactions that create tweens on the fly (
contextSafe) - Animations that depend on props or state and need to rebuild on change (
dependencies)
Use something else when
- Vanilla JS or non-React framework - use
gsap.context()directly, or no context at all - Vue components - use template refs +
onMounted/onUnmountedand callgsap.context()manually - A one-shot animation outside a React tree (e.g. a route-leave transition orchestrator) - call
gsap.to()directly
Used in these Annnimate components
- The Magnetic Button wraps its pointer-tracking tweens in
useGSAP+contextSafeso the magnetic pull cleans up on unmount - The Text Reveal component runs
SplitTextinsideuseGSAPand returns a cleanup that reverts the split before the next render - The Parallax component creates its ScrollTrigger inside
useGSAPso leaving the page kills the trigger without a manual unmount handler - The Accordion uses
useGSAPwith adependenciesarray to rebuild its open/close timeline when the active panel changes
See it running in production
Common questions
- Do I need useGSAP if I'm only animating once on mount?
- Yes - even a one-shot mount animation should use
useGSAP. Without it, you'll either leak the animation on unmount or hit StrictMode's double-invocation in dev and see the animation run twice. The hook handles both for free. - Why aren't my hover tweens cleaning up?
- Tweens created inside event handlers aren't auto-tracked. Wrap each handler in
contextSafe(provided as the second argument to youruseGSAPcallback). Anything that runs later than the initial mount and creates a tween needs the wrapper. - Can I use useGSAP in a Server Component?
- No -
useGSAPneeds the DOM. The component that uses it must be a Client Component ('use client'at the top). The page itself can stay a Server Component; only the animated leaf needs to be client. - What's the difference between useGSAP and useEffect with gsap.context()?
useGSAPis a thin wrapper overuseEffect+gsap.context()+ a StrictMode-aware cleanup. You could write it yourself, but you'd have to handle the double-invocation correctly (revert on cleanup, not just kill tweens) and remember to callctx.revert()instead ofctx.kill(). The hook does both correctly.- Does useGSAP work with ScrollTrigger?
- Yes - any ScrollTriggers created inside the callback are killed when the context reverts. You still need
gsap.registerPlugin(ScrollTrigger)once at module load, and you still need to callScrollTrigger.refresh()after async content loads, but cleanup is handled.
revert() call cleans them all up at once.NextHorizontal scrollHorizontal scroll is a scroll-driven layout where a full-viewport section is pinned in place and its inner track slides sideways as the user scrolls vertically.