Animations are what separate an ordinary website from a memorable one. They guide attention, create visual hierarchy, and make the browsing experience more enjoyable. In the React ecosystem, two tools stand out for their power and flexibility: GSAP and Motion.
GSAP: High-Impact Scroll-Based Animations
GSAP (GreenSock Animation Platform) has been around since 2008. It's used by Disney, Apple, and thousands of other companies to create spectacular web experiences.
Smooth scroll animations with ScrollTrigger
GSAP's strength lies in its ability to create animations synchronized with page scrolling:
import { gsap } from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';
gsap.registerPlugin(ScrollTrigger);
gsap.fromTo(
'.hero-title',
{ opacity: 0, y: 60 },
{
opacity: 1,
y: 0,
duration: 1,
ease: 'power3.out',
scrollTrigger: {
trigger: '.hero',
start: 'top 80%',
end: 'top 20%',
scrub: 1,
},
}
);Parallax effects for added depth
Parallax creates a sense of depth by making different elements scroll at different speeds:
gsap.to('.background-layer', {
yPercent: -30,
ease: 'none',
scrollTrigger: {
trigger: '.section',
start: 'top bottom',
end: 'bottom top',
scrub: true,
},
});Clean React integration
With @gsap/react, GSAP integrates seamlessly into React components:
import { useRef } from 'react';
import { useGSAP } from '@gsap/react';
function AnimatedSection() {
const containerRef = useRef<HTMLDivElement>(null);
useGSAP(() => {
gsap.from('.card', { opacity: 0, y: 40, stagger: 0.1 });
}, { scope: containerRef });
return <div ref={containerRef}>...</div>;
}Motion: Native Micro-Interactions for React
Motion was built specifically for React. Its declarative API fits naturally into the component paradigm, making animations intuitive to write and maintain.
Smooth enter and exit animations
AnimatePresence automatically handles exit animations when components unmount:
import { motion, AnimatePresence } from 'motion/react';
function Modal({ isOpen }: { isOpen: boolean }) {
return (
<AnimatePresence>
{isOpen && (
<motion.div
initial={{ opacity: 0, scale: 0.9 }}
animate={{ opacity: 1, scale: 1 }}
exit={{ opacity: 0, scale: 0.9 }}
transition={{ duration: 0.2 }}
>
Modal content
</motion.div>
)}
</AnimatePresence>
);
}Coordinated animations with variants
Variants let you define reusable animation states and create cascading effects:
const containerVariants = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: { staggerChildren: 0.1 },
},
};
const itemVariants = {
hidden: { opacity: 0, y: 20 },
visible: { opacity: 1, y: 0 },
};
function CardGrid({ items }: { items: Item[] }) {
return (
<motion.ul variants={containerVariants} initial="hidden" animate="visible">
{items.map(item => (
<motion.li key={item.id} variants={itemVariants}>
<Card item={item} />
</motion.li>
))}
</motion.ul>
);
}Automatic layout transitions
Motion can automatically animate size and position changes without manual calculations:
<motion.div layout>
{/* Animations happen automatically on changes */}
{isExpanded && <ExpandedContent />}
</motion.div>Combining Both Tools
On web projects, using GSAP and Motion together allows leveraging their respective strengths:
-
GSAP + ScrollTrigger: Section parallax, scroll-based global animations, header effects
-
Motion: Individual element animations (cards, text), page transitions, micro-interactions
This hybrid approach allows creating rich experiences while keeping code maintainable and performant.
Learn More
Both libraries have excellent documentation and interactive playgrounds:
-
GSAP: greensock.com - Complete documentation, active forums, varied examples
-
Motion: motion.dev - Modern API, React examples, Next.js integrations