GSAP vs Framer Motion: When I Reach for Each
I use both GSAP and Framer Motion regularly. The question I get most often is which one is better. The answer is that it is the wrong question — they solve different problems, and using the wrong one for the job makes both look bad.
Here is how I actually decide.
What each one is built for
Framer Motion is built for React. It is a declarative animation layer that integrates with React's component model — you describe the desired state, and Motion figures out how to get there. Variants let you choreograph parent-child animations. Layout animations handle element reordering automatically. The AnimatePresence component manages mount and unmount transitions.
It is excellent at what it does. The React integration is genuine — not a wrapper, but something designed around how React thinks.
GSAP is a JavaScript animation engine. It is framework-agnostic, operates directly on the DOM, and gives you precise, imperative control over timeline-sequenced animations. It has been the industry standard for high-fidelity web animation for over a decade, and plugins like ScrollTrigger and Flip have no comparable equivalents.
It is excellent at what it does. The control is genuine — down to per-frame callbacks, physics-based easing, and timeline scrubbing.
Where Framer Motion wins
Component state transitions. When an element has two or more visual states and you need to animate between them in response to React state changes, Motion's animate prop and variants system is unbeatable. You write the states, not the transitions. It handles the animation.
Mount/unmount animations. AnimatePresence is the cleanest solution I've found for animating components as they enter and leave the DOM. GSAP can do this, but it requires more ceremony — managing refs, timing the unmount to wait for the animation to finish.
Small to medium interaction animations that live inside React components. Hover states, tab switches, accordion opens, toast notifications. The Motion API is fast to write and integrates naturally with React's event model.
Where GSAP wins
Complex sequenced timelines. When you have ten elements that need to animate in a specific choreographed sequence — each triggered by the previous, with precise delays and overlaps — GSAP's timeline API has no competition. The tl.to().to().from() pattern is built for this.
ScrollTrigger. Nothing else approaches it. Scroll-driven animations with scrubbing, pinning, and progress callbacks are GSAP's territory. I've tried other scroll animation libraries and always come back.
The Flip plugin. Animating between two DOM states — a grid reorganising, a card expanding to fullscreen, items reordering — is what Flip does. You capture state before, make the DOM change, call Flip.from(). The result is smooth even across layout changes. The footer of this portfolio uses it.
Performance-critical animations. GSAP operates below React's rendering layer — directly on DOM nodes. When you need maximum frame rate (think live price tickers, continuous particle effects, 60fps scroll animations), bypassing React's reconciliation is the right call.
How I choose on a given project
If the animation lives inside a React component and responds to React state: Framer Motion first.
If the animation is a timeline sequence, scroll-driven, or requires a GSAP plugin: GSAP.
If both could work: I ask which one requires less code for the specific case. Usually that's Motion for state-based transitions and GSAP for sequenced or scroll-based work.
The trap to avoid
Using GSAP imperatively for everything that Framer Motion could handle declaratively — because you know GSAP and it feels more powerful. The result is verbose animation code inside useEffect hooks where a ten-line Motion component would have been cleaner.
The inverse trap: using Framer Motion for a complex scroll-driven sequence because the docs looked accessible, then discovering you've rebuilt a subset of ScrollTrigger with worse performance and more code.
Both are excellent tools. The skill is matching the tool to the problem, not defaulting to a favourite.