Skip to main content

Best React Animation Libraries in 2026

·PkgPulse Team
0

TL;DR

Framer Motion for most React animation needs. GSAP for complex timelines and advanced sequences. The React animation library landscape in 2026 is dominated by Framer Motion (~6M weekly downloads) which covers 90% of use cases with its gesture support and layout animations. GSAP (~3M downloads) is the choice for game-like animations and complex sequences. React Spring remains popular for physics-based animations.

Key Takeaways

  • Framer Motion: ~6M weekly downloads — most popular React animation library
  • GSAP: ~3M downloads — most powerful for complex animations
  • React Spring: ~2.5M downloads — physics-based, gesture-friendly
  • Motion (formerly Framer Motion) — rebranded to motion in 2024
  • All support TypeScript — no type definition issues

Animation Philosophy: Springs vs Tweens vs Declarative

Before comparing libraries, it's worth understanding the underlying animation models, because they reflect genuinely different philosophies about what makes animations feel good.

Duration-based (tween) animations have a fixed duration and an easing curve. You say "animate this over 300ms with ease-in-out." This is the CSS animation model, and it's predictable. The limitation is that tweens can feel mechanical when interrupted — if you start animating in one direction and immediately reverse, a tween animation snaps to the new start position rather than carrying momentum.

Spring-based physics animations simulate a physical spring with tension, friction, and mass. Rather than a fixed duration, springs animate until they reach equilibrium. This is the model used by React Spring and (by default) Framer Motion's transition system. Springs feel more natural because they carry momentum — interrupting a spring animation and reversing it produces a smooth deceleration and reversal rather than a snap. The trade-off is unpredictability: you can't say "this animation will take exactly 300ms."

Declarative animations (Framer Motion's primary model) let you describe the desired state and the library figures out how to animate to it. You say "this element should be opacity: 1, y: 0 when mounted and opacity: 0, y: -20 when unmounted." The library manages the transition automatically. This abstracts away the animation primitive (spring vs tween) and lets you focus on what the UI should look like in different states.

GSAP is the outlier — it uses an imperative, timeline-based model. You script the sequence of animations explicitly: "at t=0, start moving the box right; at t=1, start rotating it; at t=1.5, fade it out." This is less convenient for component-based UI but gives you complete control over complex choreographed sequences.


Framer Motion (motion)

Framer Motion is the default choice for React UI animations in 2026. Its API is designed for the most common animation use cases in component-based UIs: enter/exit animations, hover and tap effects, layout animations (animating size/position changes when content shifts), and gesture handling. The library's motion.div component wraps any HTML element with animation superpowers through a clean prop API.

The layout prop is one of Framer Motion's most impressive features. When you add layout to a motion.div, the library automatically animates changes in the element's size and position — even when those changes are caused by other elements reordering, content changing, or CSS responding to state. This is called FLIP (First, Last, Invert, Play) animation, and implementing it manually is notoriously difficult. Framer Motion handles it automatically.

import { motion, AnimatePresence } from 'framer-motion';

// Basic animation
function FadeIn({ children }) {
  return (
    <motion.div
      initial={{ opacity: 0, y: 20 }}
      animate={{ opacity: 1, y: 0 }}
      exit={{ opacity: 0, y: -20 }}
      transition={{ duration: 0.3 }}
    >
      {children}
    </motion.div>
  );
}

// Layout animation — smooth size/position changes
function AccordionItem({ expanded, content }) {
  return (
    <motion.div layout>
      <motion.div layout="position">Header</motion.div>
      {expanded && (
        <motion.div
          initial={{ opacity: 0, height: 0 }}
          animate={{ opacity: 1, height: 'auto' }}
          exit={{ opacity: 0, height: 0 }}
        >
          {content}
        </motion.div>
      )}
    </motion.div>
  );
}

// Gesture animations
function DraggableCard() {
  return (
    <motion.div
      drag
      dragConstraints={{ left: -100, right: 100, top: -100, bottom: 100 }}
      whileHover={{ scale: 1.05 }}
      whileTap={{ scale: 0.95 }}
    >
      Drag me
    </motion.div>
  );
}

Best for: Page transitions, hover effects, modal animations, list items, gestures.


React Spring

React Spring is built entirely around the spring physics model. Every animation is modeled as a physical spring with configurable tension, friction, and mass parameters. The library provides several hooks for different use cases: useSpring for single-value animations, useSprings for lists, useTransition for mount/unmount animations, and useChain for sequencing.

The physics model's practical advantage is interrupt handling. When a user hovers over a button and the hover animation is in progress, then quickly moves the mouse away, a spring animation carries the momentum and decelerates naturally through the reversal. Duration-based animations would snap to the reverse keyframe. For gesture-driven UIs (drag to dismiss, pull to refresh, swipe interactions), this natural feel is significant.

React Spring's useTransition hook is particularly elegant for animating list items in and out — each list item's enter/leave animation is coordinated automatically:

import { useSpring, animated, useTransition, useChain, useSpringRef } from '@react-spring/web';

// Physics-based spring animation
function PhysicsBox() {
  const [active, setActive] = useState(false);
  const style = useSpring({
    transform: active ? 'scale(1.5)' : 'scale(1)',
    backgroundColor: active ? '#6366f1' : '#e5e7eb',
    config: { tension: 300, friction: 20 }, // Spring physics
  });

  return <animated.div style={style} onClick={() => setActive(!active)} />;
}

// List transitions — mount/unmount animations
function AnimatedList({ items }) {
  const transitions = useTransition(items, {
    from: { opacity: 0, transform: 'translateX(-20px)' },
    enter: { opacity: 1, transform: 'translateX(0px)' },
    leave: { opacity: 0, transform: 'translateX(20px)' },
    keys: item => item.id,
  });

  return transitions((style, item) => (
    <animated.div style={style}>{item.name}</animated.div>
  ));
}

Best for: Physics-based animations where spring behavior feels more natural than duration-based easing.


GSAP (GreenSock)

GSAP is the most powerful JavaScript animation library in existence, but it's deliberately not component-focused. GSAP operates on DOM elements directly, using imperative timeline APIs. In a React context, you use useRef to get references to DOM elements and then pass those refs to GSAP functions. The mismatch between React's declarative model and GSAP's imperative model creates friction, but for the use cases where GSAP excels — marketing pages with complex scroll-driven animations, game UI, animated SVGs — that friction is worth accepting.

GSAP's ScrollTrigger plugin is particularly powerful, enabling scroll-driven animations that are nearly impossible to implement performantly with other libraries. The plugin handles the complexity of scroll event throttling, intersection observers, and scrubbing (linking animation progress directly to scroll position).

import { gsap } from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';

// Complex timeline animation
const tl = gsap.timeline({ repeat: -1, yoyo: true });
tl.to('.box', { x: 200, duration: 1 })
  .to('.box', { rotation: 360, duration: 0.5 })
  .to('.box', { scale: 1.5, opacity: 0.5, duration: 0.3 })
  .to('.box', { scale: 1, opacity: 1 });

// Scroll-triggered animation
gsap.registerPlugin(ScrollTrigger);
gsap.to('.hero-text', {
  y: -100,
  opacity: 0,
  scrollTrigger: {
    trigger: '.hero',
    start: 'top top',
    end: 'bottom top',
    scrub: true,
  },
});

Best for: Marketing pages with scroll animations, complex multi-step sequences, games.


Comparison Table

LibraryDownloadsBundleBest For
Framer Motion6M/wk~45KBUI animations, gestures, layout
GSAP3M/wk~75KBComplex timelines, scroll
React Spring2.5M/wk~30KBPhysics-based animations
Auto Animate1M/wk~2KBSimple list/height animations

Package Health

Framer Motion (now published as the motion package, though framer-motion still works) has strong institutional backing — it's maintained by the team behind Framer, the visual design tool, as their core technology. Regular releases and active development make it the lowest-risk choice for long-term use.

GSAP is maintained by GreenSock, a small company that has sustained active development for over a decade. Their business model (free for most uses, paid for commercial plugin licenses) is sustainable, and their reliability record is excellent. The concern with GSAP is the license: some GSAP plugins require a paid "Club GreenSock" membership for commercial use. The core GSAP package is free.

React Spring is open source and community-maintained. Development has been steady but less active than Framer Motion.

PackageWeekly DownloadsLast ReleaseGitHub StarsBacking
framer-motion / motion~6MActive (2026)23K+Framer (commercial)
gsap~3MActive (2026)20K+GreenSock (commercial)
@react-spring/web~2.5MActive (2025)28K+Community
@formkit/auto-animate~1MActive (2025)12K+FormKit

Animation Performance

The browser's rendering pipeline is the key constraint for smooth animations. The pipeline is: JavaScript → Style → Layout → Paint → Composite. Animations that trigger Layout (changing width, height, margin, padding, top, left) are expensive because the browser must recalculate element positions. Animations that only trigger Compositing (changing transform, opacity) are cheap because they run on the GPU without recalculating layout.

All modern animation libraries know this and guide you toward performant properties. Framer Motion's x, y, scale, rotate, and opacity properties map to CSS transform and opacity — the two properties that run exclusively on the compositor thread. Using these instead of left/top/width is the single most impactful animation performance decision.

// WRONG: triggers Layout recalculation
<motion.div animate={{ left: 100, top: 50 }} />

// RIGHT: uses compositor-only transform
<motion.div animate={{ x: 100, y: 50 }} />

// The will-change CSS property hints to the browser to prepare GPU layers
// Use sparingly — it consumes GPU memory
const style = {
  willChange: isAnimating ? 'transform' : 'auto',
};

Measuring animation performance requires Chrome DevTools' Performance tab. Look for "Frames" in the timeline — a smooth 60fps animation shows consistent ~16.6ms frames. Dropped frames appear as longer bars. The "Rendering" panel's "Paint flashing" option highlights elements being repainted — this should be minimal during smooth animations.

For React-specific animation performance, the key concern is JavaScript execution blocking the main thread. Long-running JavaScript during an animation will cause jank even if the animation properties are GPU-optimized. Framer Motion uses requestAnimationFrame internally and keeps JavaScript work minimal, but complex animation logic in your component code can still block frames.

// Identifying jank — use Performance Observer
const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    if (entry.duration > 50) { // Long task (>50ms blocks main thread)
      console.warn('Long task during animation:', entry.duration, 'ms');
    }
  }
});
observer.observe({ entryTypes: ['longtask'] });

Page Transitions

Page transitions in Next.js App Router require specific handling because the App Router doesn't unmount the previous page before mounting the new one in the same way pages worked in the Pages Router. AnimatePresence from Framer Motion is the standard solution, but it requires careful integration with the routing lifecycle.

The pattern that works in 2026 with Next.js App Router uses a layout component that wraps page content in AnimatePresence and uses the route pathname as the key:

// app/layout.tsx — page transition wrapper
'use client';
import { AnimatePresence, motion } from 'framer-motion';
import { usePathname } from 'next/navigation';

const pageVariants = {
  initial: { opacity: 0, y: 20 },
  in: { opacity: 1, y: 0 },
  out: { opacity: 0, y: -20 },
};

const pageTransition = {
  type: 'tween',
  ease: 'anticipate',
  duration: 0.3,
};

export default function RootLayout({ children }) {
  const pathname = usePathname();

  return (
    <html>
      <body>
        <AnimatePresence mode="wait" initial={false}>
          <motion.main
            key={pathname}
            initial="initial"
            animate="in"
            exit="out"
            variants={pageVariants}
            transition={pageTransition}
          >
            {children}
          </motion.main>
        </AnimatePresence>
      </body>
    </html>
  );
}

The mode="wait" option in AnimatePresence ensures the exit animation completes before the enter animation begins — preventing the old and new pages from being visible simultaneously. The key={pathname} change triggers the animation when the route changes.

For enter animations on specific page elements (hero text fading in, staggered list items), use motion components directly in your page components with initial and animate props. These trigger on mount regardless of the page transition wrapper.


When to Choose

  • Framer Motion — default choice for React apps; covers 90% of needs
  • GSAP — marketing sites, scroll-driven animations, complex sequences
  • React Spring — when spring physics feel is specifically desired
  • Auto Animate — drop-in 2KB solution for simple list animations only

Check animation library health scores and download trends on PkgPulse. For building performant React UIs, see best React form libraries 2026. Explore the full PkgPulse package directory.

The 2026 JavaScript Stack Cheatsheet

One PDF: the best package for every category (ORMs, bundlers, auth, testing, state management). Used by 500+ devs. Free, updated monthly.