React

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

Mechanics

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.

Component.jsx

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.

contextSafe

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.

Component.jsx
When

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)
Alternatives

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 / onUnmounted and call gsap.context() manually
  • A one-shot animation outside a React tree (e.g. a route-leave transition orchestrator) - call gsap.to() directly
In production

Used in these Annnimate components

  • The Magnetic Button wraps its pointer-tracking tweens in useGSAP + contextSafe so the magnetic pull cleans up on unmount
  • The Text Reveal component runs SplitText inside useGSAP and returns a cleanup that reverts the split before the next render
  • The Parallax component creates its ScrollTrigger inside useGSAP so leaving the page kills the trigger without a manual unmount handler
  • The Accordion uses useGSAP with a dependencies array to rebuild its open/close timeline when the active panel changes
Used in components

See it running in production

FAQ

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 your useGSAP callback). Anything that runs later than the initial mount and creates a tween needs the wrapper.
Can I use useGSAP in a Server Component?
No - useGSAP needs 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()?
useGSAP is a thin wrapper over useEffect + 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 call ctx.revert() instead of ctx.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 call ScrollTrigger.refresh() after async content loads, but cleanup is handled.