GSAP vs Framer Motion vs React Spring: Which Should You Use in 2026?
Comparing GSAP, Framer Motion, and React Spring for React animation. Bundle sizes, performance data, code examples, and honest recommendations.

Estimated reading time: 12 minutes | Skill level: Intermediate
Every React developer hits this wall. You need animations. You search around. Three names keep coming up: GSAP, Framer Motion, React Spring. They all say they're the best. They all have fans who swear by them.
I've used all three in production. Here's what I actually think.
Quick answer: GSAP for anything complex or performance-critical. Framer Motion for layout animations and exit transitions in UI-heavy apps. React Spring if you want physics-based motion with a small API surface.
For most production work, I reach for GSAP.
What Is Each Library?
GSAP (GreenSock Animation Platform)
GSAP is a JavaScript animation library built by GreenSock. It's been the industry standard for professional web animation for over 15 years. Disney, Google, Amazon, Apple, and Stripe all use it.
It's not React-specific. It works anywhere: vanilla JS, React, Vue, Svelte, plain HTML. In React, you use theuseGSAP@gsap/reactCore bundle size: 23KB gzipped (core, no plugins)
Key features:
- Timeline sequencing with precise control over every keyframe
- ScrollTrigger plugin for scroll-linked animations (pinning, scrubbing, parallax)
- SplitText for character and word-level text animations
- All plugins free since v3.12 (2023)
- Runs at 60fps on mobile, not just desktop
Best for: Complex sequences, scroll animations, text reveals, award-level sites.
Framer Motion
Framer Motion is a React animation library built by the Framer team. It's declarative and feels very native to React. You animate by changing props on motion components.
It's React-only. There's no vanilla JS version.
Core bundle size: 46KB gzipped (full package, with tree shaking closer to 34KB for basic usage)
Key features:
- for exit animations when components unmount
AnimatePresence - Layout animations (prop) for smooth DOM reordering
layout - Gesture animations (drag, hover, tap) with minimal code
- Variants system for coordinating animations across component trees
Best for: UI animations, exit animations, layout transitions, drag interactions.
React Spring
React Spring is a physics-based animation library for React. Instead of duration-based tweens, it uses spring simulations. Animations feel natural because they behave like real physics.
Core bundle size: 18KB gzipped (@react-spring/web)
Key features:
- Spring physics model (tension, friction, mass)
- ,
useSpring,useSprings,useTrailhooksuseChain - Interpolation system for complex value transforms
- Works with for 3D animations
react-three-fiber
Best for: Small-to-medium UI animations where natural motion feel matters more than precise timing.
Feature Comparison
| Feature | GSAP | Framer Motion | React Spring |
|---|---|---|---|
| Bundle size (gzipped) | 23KB | 34-46KB | 18KB |
| React-specific | No | Yes | Yes |
| Scroll animations | Yes (ScrollTrigger) | Basic only | No |
| Exit animations | Manual | Yes (AnimatePresence) | Manual |
| Layout animations | Manual | Yes (layout prop) | No |
| Timeline/sequencing | Yes (best in class) | Limited | useChain |
| Physics-based | No | Partial | Yes |
| SVG animation | Yes | Partial | No |
| Text animation | Yes (SplitText) | No | No |
| Learning curve | Medium | Low | Low |
| Free plugins | Yes (since 2023) | N/A | N/A |
Performance: The Real Difference
All three libraries can hit 60fps for simple animations. The gap shows up at scale.
How GSAP Handles Rendering
GSAP updates CSS properties directly via a singlerequestAnimationFrameCritically: GSAP animations do not trigger React's reconciler. When a GSAP tween runs, React doesn't know about it. No virtual DOM diffing. No re-renders. Just direct DOM manipulation.
This matters on mobile. An iPhone 13 handles a 40-element staggered entrance animation at 60fps with GSAP. The same animation with React state updates causing re-renders can drop to 45-50fps.
How Framer Motion Handles Rendering
Framer Motion uses the Web Animations API for simple transforms and opacity (GPU-accelerated, no re-renders). But layout animations (layoutIn practice: Framer Motion is fast for simple animations. Layout animations on large lists can get expensive. I've seen layout animations with 50+ items cause noticeable jank on mid-range Android.
How React Spring Handles Rendering
React Spring uses a shared value system similar to Framer Motion's. Most animations don't trigger full re-renders. The spring physics model is computed off the main thread where possible.
The issue: spring animations never truly "finish." They approach their target asymptotically. React Spring has a rest threshold, but small residual forces continue calculating until the threshold is hit. For many short animations this is imperceptible. For 30+ simultaneous springs it adds up.
Performance Summary
For a single button hover or a fade-in: all three perform identically. You won't see a difference.
For a page with 15+ scroll-triggered animations, complex sequencing, or 60+ elements animating together: GSAP has a clear advantage. Its architecture was built for this.
Developer Experience
GSAP in React
The modern way to use GSAP in React is theuseGSAPimport { useRef } from 'react';
import { gsap } from 'gsap';
import { useGSAP } from '@gsap/react';
export default function HeroSection() {
const container = useRef(null);
useGSAP(() => {
gsap.from('.hero-title', {
opacity: 0,
y: 60,
duration: 0.8,
ease: 'expo.out',
});
gsap.from('.hero-subtitle', {
opacity: 0,
y: 40,
duration: 0.8,
delay: 0.15,
ease: 'expo.out',
});
}, { scope: container });
return (
<section ref={container}>
<h1 className="hero-title">Build Better Animations</h1>
<p className="hero-subtitle">Copy-paste GSAP components for React.</p>
</section>
);
}
useGSAPPros:
- Complete control over every frame
- Timeline API is unmatched for complex sequences
- Works the same in React, Vue, vanilla JS
- Free plugins (SplitText, ScrollTrigger, MorphSVG, all of them)
Cons:
- Steeper learning curve than Framer Motion
- Exit animations require manual handling (no built-in unmount lifecycle)
- More verbose for simple animations
Framer Motion in React
Framer Motion wraps your HTML inmotion.*initialanimateexitimport { motion, AnimatePresence } from 'framer-motion';
export default function Modal({ isOpen, onClose }) {
return (
<AnimatePresence>
{isOpen && (
<motion.div
initial={{ opacity: 0, scale: 0.95 }}
animate={{ opacity: 1, scale: 1 }}
exit={{ opacity: 0, scale: 0.95 }}
transition={{ duration: 0.2, ease: 'easeOut' }}
className="modal"
>
<p>Modal content</p>
<button onClick={onClose}>Close</button>
</motion.div>
)}
</AnimatePresence>
);
}
AnimatePresencePros:
- Low learning curve
- for exit animations is best in class
AnimatePresence - Layout animations with zero math
- Feels native to React's declarative model
Cons:
- Larger bundle than GSAP core
- Complex sequences are awkward (variants can get messy)
- No scroll-triggered animations without third-party libraries
- Owned by Framer (a commercial company), not open governance
React Spring in React
React Spring uses hooks to return animated values. You apply those values to DOM elements viaanimated.*import { useSpring, animated } from '@react-spring/web';
export default function AnimatedCard({ isVisible }) {
const styles = useSpring({
opacity: isVisible ? 1 : 0,
transform: isVisible ? 'translateY(0px)' : 'translateY(30px)',
config: { tension: 280, friction: 60 },
});
return (
<animated.div style={styles} className="card">
Card content
</animated.div>
);
}
useChainPros:
- Smallest bundle
- Natural, physics-based motion
- Good for 3D with react-three-fiber
- Less verbose than GSAP for simple cases
Cons:
- No scroll animation support
- No text animation support
- Complex sequences are harder than they should be
- Physics model can feel unpredictable until you know the config values
Bundle Size: What It Costs You
A 1KB increase in JavaScript adds about 2ms of parse time on a mid-range Android device (Lighthouse data, Moto G4 class).
| Library | Bundle (gzipped) | Est. parse overhead (mobile) |
|---|---|---|
| React Spring | 18KB | ~36ms |
| GSAP core | 23KB | ~46ms |
| Framer Motion (tree-shaken) | 34KB | ~68ms |
| Framer Motion (full) | 46KB | ~92ms |
For context: Google recommends keeping total JavaScript under 200KB gzipped for fast initial load. A 46KB animation library is 23% of that budget.
This doesn't mean Framer Motion is a bad choice. It means you should weigh it if you're performance-sensitive or working on pages where load time matters.
GSAP's 23KB core covers most use cases. If you add ScrollTrigger, add another ~7KB. SplitText adds ~4KB. You're still under 35KB for a full production animation setup.
When to Use Each Library
Use GSAP if you're:
- Building scroll-driven animations (ScrollTrigger is the best tool for this, period)
- Animating text with character/word-level control (SplitText)
- Sequencing complex multi-step animations across multiple elements
- Building agency/portfolio/marketing sites where animation is the focus
- Working across frameworks (you use React now but might use Vue or vanilla later)
- Coming from after-effects or motion design (the timeline model is familiar)
Example project: A product launch page with scroll-pinned sections, text reveals, parallax layers, and a staggered hero entrance. This is GSAP territory.
// GSAP timeline: sequence 6 elements with 1 line of stagger
gsap.from('.feature-card', {
opacity: 0,
y: 50,
duration: 0.6,
stagger: 0.1,
ease: 'expo.out',
scrollTrigger: {
trigger: '.features-section',
start: 'top 80%',
},
});
Use Framer Motion if you're:
- Building a React app with lots of UI state transitions (modals, drawers, tabs, accordions)
- You need exit animations when components unmount (is genuinely the best solution here)
AnimatePresence - Working with drag interactions
- Animating list reordering or layout changes
Example project: A Notion-like editor where cards reorder, modals open/close, and sidebar sections collapse. Exit animations and layout animations are everywhere. Framer Motion handles this with almost no custom code.
// Framer Motion: layout animation, zero math required
<motion.li layout key={item.id}>
{item.content}
</motion.li>
Use React Spring if you're:
- Building small-to-medium UI components where natural motion feel is the goal
- Working with for 3D
react-three-fiber - You want the smallest possible animation bundle
- Spring physics model fits your use case (bouncy, elastic, natural)
Example project: A settings panel with toggle switches, accordion menus, and counter animations. React Spring's spring config makes these feel satisfying with minimal code.
My Verdict
I use GSAP for almost everything. The free plugins since 2023 removed the last reason I had to reach for alternatives. SplitText, ScrollTrigger, MorphSVG: all free, all in one package.
For Annnimate, every component is built with GSAP. Not because I'm biased (well, a little), but because when I need to reproduce animations reliably across projects with different frameworks and environments, GSAP just works. Predictable, well-documented, battle-tested.
Choose GSAP if:
- Animation is a primary feature of what you're building
- You need scroll animations
- Performance on mobile matters
- You want one library that works everywhere
Choose Framer Motion if:
- You're building a React app (not a site) where UI state transitions dominate
- You need exit animations without writing your own lifecycle handling
- The team is less experienced with animation and needs a lower learning curve
Choose React Spring if:
- Bundle size is critical
- You're working in 3D with react-three-fiber
- Spring physics model fits your specific use case
For most production sites: GSAP. It's what the best studios use for a reason.
Practical Starting Points
If you want to see what production-ready GSAP animations look like before writing them from scratch, I've built 42+ copy-paste components at Annnimate. Everything from scroll reveals to button hover effects to text animations. All with real code in React and HTML.
Key Takeaways
- GSAP: 23KB gzipped, best performance, best for scroll and complex sequences
- Framer Motion: 34-46KB gzipped, best for exit animations and layout transitions in React apps
- React Spring: 18KB gzipped, physics-based, good for 3D and natural-feeling UI
- For production sites and marketing pages: GSAP
- For React apps with lots of UI state: Framer Motion
Related
Written by
Julian Fella
Founder
Related reading

GSAP ScrollTrigger Tutorial: Animate on Scroll (2025)
Learn GSAP ScrollTrigger with step-by-step examples. Includes code snippets, performance tips, and ready-to-use scroll animations for your project.