← Back to blog
··14 min read

Framer Motion vs GSAP vs React Spring in 2026: Which Animation Library Should You Use

Framer MotionMotionGSAPReact SpringAnimationReactNext.jsTypeScriptLanding Pages
Framer Motion vs GSAP vs React Spring in 2026: Which Animation Library Should You Use

The Layer That Makes an Interface Feel Alive

Every landing page, portfolio, and product UI eventually wants the same thing: motion that guides the eye and makes the product feel considered. You *could* hand-write @keyframes and CSS transitions — but they fall apart fast once you need elements to animate *out* as well as in, to react to gestures, to sequence in a precise order, or to respond to scroll. An animation library gives you enter/exit transitions, springs, gestures, timelines, and scroll triggers for free, so you spend your time on the *feel*, not the plumbing.

In the React world of 2026, three names come up again and again, and they made genuinely different bets. Motion — the library everyone learned as Framer Motion — is the declarative default that feels like writing React. GSAP is the imperative, timeline-based engine that owns complex choreography and scroll storytelling. React Spring is the physics-first library where every animation is a real spring. This guide compares them through two lenses: which is better to build on, and which produces a page that's clean to hand off or sell.

Abstract neon light trails suggesting motion

Abstract neon light trails suggesting motion

A Quick Note on the Name: Framer Motion Is Now "Motion"

Before the comparison, clear up the naming, because it confuses everyone. The library published for years as Framer Motion was renamed and now ships as the motion package, imported in React from motion/react. It's the same declarative, spring-based library — motion.div, the animate/whileHover props, AnimatePresence, layout animations — just under a broader name, because Motion now *also* offers a vanilla-JS API for use outside React. Every "Framer Motion" tutorial you find still applies; only the package name and import path changed. Throughout this guide, "Motion" means exactly that library.

First, What These Tools Actually Share

All three solve the same core problem, so it helps to name it before comparing. An animation library:

  • Animates values over time — position, opacity, scale, color, SVG paths — from one state to another.
  • Handles easing and physics — smooth curves or spring dynamics instead of linear jumps.
  • Manages enter and exit — animating elements in *and* out as they mount and unmount.
  • Adds interaction — hover, tap, drag, and scroll-linked motion.
  • The differences are in *how* they do it — declarative props vs an imperative timeline, fixed-duration tweens vs spring physics, React-native vs framework-agnostic — and that's where developer experience, choreography power, and portability diverge.

    At a Glance

    Motion (Framer Motion)GSAPReact Spring
    ModelDeclarative propsImperative timelineDeclarative hooks
    Motion styleSprings + tweensTweens + timelinesSpring physics
    React fitNative (`motion/react`)Framework-agnostic, via effectsNative (hooks)
    Enter/exit`AnimatePresence`ManualVia transitions
    Scroll choreographyGood (scroll utilities)Excellent (ScrollTrigger)Basic
    GesturesBuilt-in (drag/hover/tap)ManualStrong (with gesture lib)
    Timelines / sequencingGoodBest-in-classChained/sequenced
    SVG morph / drawBasicBest-in-classBasic
    TypeScriptSolidSolidSolid
    Best fitTypical UI + landing pagesChoreography + scroll storiesPhysics-driven, gesture UI

    Note: all three evolve quickly — Framer Motion became Motion, and GSAP was relicensed fully free (plugins included). Treat this table as a map, not a spec sheet, and verify current behavior against the official docs before you commit.

    The Design Decision That Explains Each One

    Almost every difference below follows from one bet each tool made about how you should describe an animation.

    Motion: declarative animation that reads like React

    Motion's bet is that an animation should be a prop on a component, the same way you build any other React UI. You turn a div into a motion.div and describe the states you want; Motion handles the transition — with spring defaults that feel natural out of the box.

    tsx
    // Motion — animation is just props
    "use client";
    import { motion, AnimatePresence } from "motion/react";
    
    export function Card({ open }: { open: boolean }) {
      return (
        <AnimatePresence>
          {open && (
            <motion.div
              initial={{ opacity: 0, y: 12 }}
              animate={{ opacity: 1, y: 0 }}
              exit={{ opacity: 0, y: 12 }}
              whileHover={{ scale: 1.03 }}
            >
              Hello
            </motion.div>
          )}
        </AnimatePresence>
      );
    }

    What you get is the most React-native developer experience of the three: animations read like your other components, TypeScript flows through, exit animations and layout transitions are first-class, and gestures (drag, hover, tap) are built in. It's also the most widely used React animation library, so examples and AI-assistant familiarity are abundant. What you pay is a bit less raw control over precise multi-step timelines than GSAP. For the vast majority of interface motion, that's no cost at all — which is why Motion is the sensible default, the same "pick the lean, idiomatic option" instinct behind choosing a good tech stack for web apps in 2026.

    GSAP: an imperative timeline engine

    GSAP's bet predates the React era: expose a powerful animation engine you command imperatively, and let it run anywhere. In React you drive it from inside an effect, targeting elements by ref and sequencing them on a timeline.

    tsx
    // GSAP — an imperative timeline, scoped to the component
    "use client";
    import { useRef } from "react";
    import { useGSAP } from "@gsap/react";
    import gsap from "gsap";
    
    export function Hero() {
      const scope = useRef<HTMLDivElement>(null);
    
      useGSAP(
        () => {
          const tl = gsap.timeline();
          tl.from(".title", { y: 40, opacity: 0, duration: 0.6 })
            .from(".subtitle", { y: 20, opacity: 0 }, "-=0.3");
        },
        { scope }
      );
    
      return (
        <div ref={scope}>
          <h1 className="title">Ship it</h1>
          <p className="subtitle">Animated with GSAP</p>
        </div>
      );
    }

    What you get is unmatched choreography: precise sequencing with offsets and overlaps, SVG morphing and drawing, text splitting, and — the headliner — ScrollTrigger for pinning and scroll-linked storytelling. It's also now completely free, plugins included, after its Webflow-era relicensing. What you pay is that it's not React-native: you run it imperatively and manage scoping and cleanup (the useGSAP helper does this for you). Reach for it when choreography or scroll is the point.

    React Spring: motion modeled as real springs

    React Spring's bet is that animation should be physical. Instead of fixed durations, every value is a spring with tension, friction, and mass — so motion settles naturally and, crucially, can be interrupted mid-flight without snapping.

    tsx
    // React Spring — declarative, hook-based, physics-driven
    "use client";
    import { useSpring, animated } from "@react-spring/web";
    
    export function Toggle({ on }: { on: boolean }) {
      const styles = useSpring({ x: on ? 24 : 0, opacity: on ? 1 : 0.4 });
      return <animated.div style={styles}>Slide</animated.div>;
    }

    What you get is interruptible, lifelike motion — ideal for draggable cards, sheets, and gesture-driven UI where the animation must react to the user in real time. What you pay is a hook-based mental model that's a touch steeper than dropping props on an element, and less turnkey scroll/timeline tooling. It's the pick when spring physics and gesture interruption are the core idea, not a garnish.

    Colorful flowing gradient suggesting fluid motion

    Colorful flowing gradient suggesting fluid motion

    The Fork That Decides Most Cases: Declarative vs Imperative

    If you remember one thing, make it this. Motion and React Spring are declarative; GSAP is imperative — and that single fact drives how each fits a React codebase.

    With a declarative library, you describe the *state* an element should be in and let the library transition to it. The animation lives in your JSX, reacts to props and state, and reads like the rest of your components — there's almost no imperative wiring to manage. That's why Motion and React Spring feel at home in React: the animation is part of the render.

    With an imperative engine, you issue *commands* — move this, then fade that, over these durations — usually inside an effect against real element refs. That gives you exact, frame-level control over sequencing and is unmatched for complex choreography, but it sits outside React's model, so you own the "run it at the right time and clean it up on unmount" part (GSAP's useGSAP helper handles the scoping and reverting for you).

    The practical rule: declarative (Motion, React Spring) for animation that's part of your UI state; imperative (GSAP) when you need to script a precise, multi-step or scroll-driven sequence. Most interface animation is the former — which is exactly why a declarative library is the default recommendation.

    Developer Experience: Props vs Hooks vs Timelines

    This is the difference you feel on every animation you write, and it mirrors a theme that runs through the whole modern stack: tools that match how React already works win on day-to-day friction.

  • Motionprops on components. initial, animate, exit, whileHover. It reads like the rest of your app, which is why it's the easiest for a teammate — or a buyer of your template — to edit.
  • React Springhooks. useSpring, useTransition, bound to animated elements. Powerful and physical, a bit more to internalize.
  • GSAPa timeline you script. Maximum control over sequencing, but you write it imperatively and manage lifecycle.
  • The DX gap is the same reason a fast package manager and a clean linter setup matter: shaving friction off the thing you do repeatedly compounds. For motion you'll add and tweak across a whole page, the declarative, React-native model keeps the code approachable — and TypeScript types flowing through it keep it refactorable.

    Server Rendering and the Next.js App Router

    For a Next.js page, none of these fundamentally fights SSR — but animation is interactive, so the animated parts run on the client, and the discipline is to isolate the interactive island.

  • Motion and React Spring use hooks and browser APIs, so the component that animates is a client component — mark it "use client". Keep the surrounding static markup in server components for the SEO and performance win.
  • GSAP needs the DOM and runs after mount inside an effect, so it's client-side by nature; ScrollTrigger is browser-only. Same rule: a small "use client" island, with animations scoped and cleaned up.
  • tsx
    // The pattern for all three: a small client island in a server page
    import { HeroAnimation } from "./hero-animation"; // "use client" inside
    
    export default function Page() {
      return (
        <main>
          <h1>Static, server-rendered headline</h1>
          <HeroAnimation /> {/* the only client component */}
        </main>
      );
    }

    For a template you hand off, doing that isolation cleanly — and avoiding hydration warnings — is a real advantage, one less sharp edge for the buyer to cut themselves on, and part of why Motion stays the default for Next.js interfaces.

    Developer workspace with clean, organized code

    Developer workspace with clean, organized code

    Accessibility: Respect Reduced Motion

    Whichever library you pick, one rule is non-negotiable: honor the user's prefers-reduced-motion setting. Large parallax, big movement, and auto-playing motion can cause real discomfort for some users. Motion exposes a useReducedMotion hook; GSAP can gate animations behind gsap.matchMedia(); React Spring can read the media query and flatten springs. A template that ignores this isn't just inconsiderate — it reads as unfinished. Building the reduced-motion path in from the start is exactly the kind of detail that separates production-ready code from a demo.

    Which Reads Better When You Sell the Code

    If you build landing pages or portfolio templates to sell — the whole point of CodeCudos — the animation library is a signal buyers read for how current and maintainable the code is, exactly like the styling approach or the language choice.

    For animation, the honest advice is default to the most React-native option, and deviate only for a stated reason:

    Selling a typical React or Next.js landing page or app UI? Ship Motion. Its declarative props read like the rest of the codebase, so a buyer can turn a fade into a slide, retune a hover, or restage a section's entrance without learning a new mental model. It's typed, it isolates cleanly into a client island, and it's the most widely-used React animation library — all of which read as "production-ready." This is the safe default for most React templates.

    Selling a heavily choreographed or scroll-driven site? Ship GSAP for the timeline and ScrollTrigger power — but scope and clean up the animations (use useGSAP) and document that they're client-side. A GSAP effect that leaks or throws on navigation is exactly the broken first run that destroys buyer trust.

    Selling a gesture-driven, physics-forward UI? Ship React Spring when interruptible spring motion is the headline feature, and accept the steeper hooks model as the cost.

    Whatever applies, the resale signal is the same as with any tooling choice — coherence and a clean first run:

  • Pick the library the framework's typical buyer already recognises.
  • A fresh install should animate on the first try, with no console errors or hydration warnings.
  • Respect reduced motion so the page is considerate by default.
  • Keep the dependency current so the buyer inherits maintained code.
  • Animations that jank, warn on load, or ignore accessibility undercut the "production-ready" impression no matter how impressive the effect — the same coherence-over-hype standard that keeps any codebase credible.

    How to Choose

    Choose Motion (Framer Motion) if:

  • You're building a typical React or Next.js UI or landing page with fades, slides, staggers, and hover states
  • You want the most React-native, declarative API and easy TypeScript types
  • You need enter/exit and layout animations and built-in gestures without extra libraries
  • You're shipping a template to sell that buyers must understand fast
  • Choose GSAP if:

  • You're building complex choreography — precise multi-step timelines with offsets and overlaps
  • You need scroll storytelling (pinning, scroll-linked reveals) via ScrollTrigger
  • You want SVG morphing/drawing or advanced text animation
  • You're comfortable driving an imperative engine from inside React and scoping cleanup
  • Choose React Spring if:

  • Physics-based, interruptible motion is the core experience
  • You're building gesture-driven UI — draggable cards, sheets, sliders that react in real time
  • You prefer a hook-based declarative model and want springs, not fixed durations
  • Lifelike, continuously-reactive motion is the headline feature
  • If you're still unsure:

    Default to Motion. It's the React-native option, it covers the common cases with the least friction, it isolates cleanly in the App Router, and it's the most widely understood — so it's the lowest-risk pick for a page you build, maintain, or sell. Move to GSAP only when choreography or scroll demands a timeline engine, and to React Spring only when spring physics and gesture interruption are the point.

    The Bottom Line

    There's no universal winner — there's a right animation library for what kind of motion you're building and who inherits the code.

  • "A normal React/Next.js UI or landing page" → Motion (Framer Motion)
  • "Timeline choreography or scroll storytelling" → GSAP
  • "Physics-driven, gesture-interruptible motion" → React Spring
  • "Selling a template that must read as modern" → Motion, unless a stated choreography or physics need says otherwise
  • Whichever you choose, the habit that outlasts the decision is the same: pick the library that matches how your framework and buyers already think, make sure a fresh install animates on the first try, and respect reduced motion. That discipline costs almost nothing and pays back on every page you build and every handoff.

    Ready to turn what you build into income? List your landing page or template on CodeCudos, see how the animation layer fits the wider stack in our best tech stack for web apps in 2026 guide, browse what sells with our best landing page templates to buy in 2026 roundup, pick the framework it sits under with Next.js vs Astro vs SvelteKit, or make sure the whole codebase reads as production-ready.

    Frequently asked questions

    Is Framer Motion the same thing as Motion now?

    Effectively yes, and it's worth being precise because the naming trips people up. The library that everyone learned as 'Framer Motion' was renamed and is now published simply as Motion, installed as the `motion` package and imported in React from `motion/react` (older code imports the same components from `framer-motion`, and that entry point still works). It's the same declarative, spring-based animation library — `motion.div`, the `animate` and `whileHover` props, `AnimatePresence` for exit animations, and layout animations — just under a broader name, because Motion now also ships a vanilla-JavaScript API for use outside React. So when you read a 2023-era 'Framer Motion' tutorial, the concepts map one-to-one onto today's Motion; the main change you'll notice is the package name and import path. For a React or Next.js project the practical takeaway is unchanged: reach for `motion/react`, write animations as props on `motion` elements, and treat every 'Framer Motion' resource you find as current Motion documentation. The rename doesn't change the recommendation — it's still the React-native default for the majority of interface animation.

    What's the real difference between declarative and imperative animation?

    It's the single most important fork between these libraries, and it decides how each one fits into a React codebase. Motion and React Spring are declarative: you describe the state you want an element to be in — 'this should be visible and shifted up' — and the library figures out the transition, expressed as props or hooks that live inside your JSX. That maps cleanly onto how React already works: your animation is part of the component's render, it reacts to state and props, and there's little imperative wiring to manage. GSAP is imperative: you issue commands to an animation engine — 'move this element to x over 0.5 seconds, then fade that one in' — typically by grabbing element references and running a timeline inside an effect. That gives you exact, frame-level control over sequencing and is unmatched for complex choreography, but it sits outside React's declarative model, so you're responsible for running it at the right time and cleaning it up when the component unmounts. The practical rule: declarative (Motion, React Spring) for animation that's part of your UI state and should read like the rest of your components; imperative (GSAP) when you need to script a precise, multi-step sequence that a props-based API would make awkward. Most interface animation is the former, which is why a declarative library is the default recommendation — but scroll-driven storytelling and tightly-timed sequences are exactly where the imperative model earns its place.

    Which one is the safest default for a typical React app?

    Motion, for a specific and boring reason: it maps most cleanly onto how React developers already think, and it covers the ordinary cases with the least friction. Its API is declarative — you turn a `div` into a `motion.div` and animate it with props like `initial`, `animate`, `exit`, `whileHover`, and `whileTap`, the same way you'd pass any other prop — so an animation reads like the rest of your component, TypeScript types flow through, and a teammate (or a buyer of your template) can understand and edit it without learning a separate mental model. It handles the things real interfaces actually need: mount/unmount transitions through `AnimatePresence`, automatic layout animations when elements reflow, drag and tap gestures, and scroll-linked effects — and its spring defaults feel natural without tuning. It's also the most widely used React-native animation library, which in practice means the most tutorials, the most example code, and the most AI-assistant familiarity, a real productivity factor. For the fades, slides, staggered lists, hover states, and page transitions that make up the overwhelming majority of UI motion, Motion gets you there with minimal code. You'd move off this default only when a concrete need — precise timeline choreography (GSAP) or physics-first interruptible motion (React Spring) — outweighs the convenience of the tool that feels most like React.

    When is GSAP the right choice over Motion, and is it really free now?

    Reach for GSAP when the animation is a choreographed sequence or a scroll-driven story rather than a handful of independent UI transitions. GSAP is a mature, framework-agnostic animation engine built around timelines: you can line up a dozen steps with precise offsets, overlaps, and easing, morph and draw SVG paths, split and animate text, and — most importantly — build scroll-linked experiences with ScrollTrigger, where elements pin, reveal, and progress as the user scrolls. That kind of tightly-timed, multi-element choreography is awkward to express as declarative props and is exactly what GSAP was built for; it's the tool behind a large share of award-winning marketing and portfolio sites. And yes — as of the Webflow-era relicensing, GSAP is now completely free, including the plugins (ScrollTrigger, SplitText, MorphSVG, and the rest) that were previously behind a paid membership, so the old 'the good plugins cost money' caveat no longer applies. The tradeoff is architectural: GSAP isn't React-native, so in a React or Next.js app you run it imperatively — grab element refs, create the animation or timeline inside an effect, and clean it up on unmount (the modern pattern uses GSAP's React helper to scope and revert animations automatically). So choose GSAP when choreography and scroll storytelling are the point and you're comfortable driving an imperative engine from inside React; stay on Motion when the animation is ordinary UI state and you want it to read like your components.

    When does React Spring make more sense than Motion?

    React Spring is the pick when motion should feel physical and be freely interruptible — most obviously in gesture-driven interfaces. Instead of animating for a fixed duration, React Spring models every animation as a real spring with tension, friction, and mass, so values settle naturally and, crucially, respond mid-flight: if a user grabs a card that's still animating and flings it the other way, the motion redirects smoothly instead of snapping or queueing. That makes it excellent for draggable cards, sheets, sliders, pull-to-refresh, and any UI where the user is in continuous control and the animation has to react to them in real time (it pairs naturally with a gesture library for exactly this). It's declarative like Motion but hook-based — you call `useSpring` and bind the animated values to elements — which is powerful but a slightly steeper mental model than dropping props on a `motion` element. Worth knowing: Motion also has strong spring support and gesture handling, so the two overlap more than they used to; the case for React Spring is strongest when spring physics and interruptibility are the central design idea of the interface rather than a nice-to-have. So choose React Spring when physics-driven, gesture-interruptible motion is the core experience; choose Motion when you want the broadest, most approachable declarative toolkit for general UI animation.

    Do these work with server-side rendering and the Next.js App Router?

    All three can be used in a Next.js App Router project, but animation is inherently interactive, so in practice the animated parts run on the client — and how you wire that in differs. Motion is built with React in mind and works cleanly in the App Router; because its components use browser APIs and hooks, you mark the file that renders them with 'use client', and Motion additionally provides tooling (like its `LazyMotion` and a dedicated server-safe entry) to keep bundles small and avoid hydration mismatches. React Spring is the same shape: it's hook-based and client-side, so the component that uses `useSpring` is a client component with 'use client'. GSAP depends on the DOM and typically on refs to real elements, so it must run in the browser after mount — you put it in a client component and start the animation inside an effect (its React helper scopes and cleans things up for you); if it also uses ScrollTrigger, that's browser-only by nature. The unifying rule for the App Router is simple: keep static markup in server components for the SEO and performance win, and push the animated piece into a small client component marked 'use client'. None of the three fundamentally fights SSR, but all of them animate on the client, so the discipline is to isolate the interactive island rather than turn a whole page into a client component. For a template you hand off, doing that isolation cleanly is part of what makes the code read as production-ready.

    Which animation library should a landing-page or portfolio template ship with?

    For a React or Next.js landing page or portfolio you intend to hand off or sell, Motion is almost always the right default — and the reasoning is about the buyer, not just the technology. A template's job is to be immediately understandable and editable by whoever buys it, and Motion's declarative props read like the rest of a React codebase, so a buyer can change a fade into a slide, adjust a hover effect, or restage a section's entrance without learning a separate animation mental model. It's fully typed, it isolates cleanly into a client island in the App Router, and it's the most widely used React animation library, so the buyer can find answers and examples easily — all signals that read as 'production-ready.' Ship GSAP in a template when the product's selling point is choreography or scroll storytelling — an animated agency site, a heavily scroll-driven portfolio — and if you do, scope and clean up the animations properly (use its React helper) and document that it's client-side, because a GSAP effect that leaks or throws on navigation is exactly the kind of broken first run that destroys buyer trust. Ship React Spring when the template is built around gesture-driven, physics-based interaction and that's the headline feature. Whichever you choose, the resale rule is the same as for every other tooling decision: pick the library the framework's typical buyer already recognises, make sure a fresh install animates on the first try without console errors or hydration warnings, keep the dependency current, and respect users' reduced-motion preference. Animations that jank, warn on load, or ignore accessibility undercut the whole production-ready impression no matter how impressive the effect.

    Related guides

    Browse Quality-Scored Code

    Every listing on CodeCudos is analyzed for code quality, security, and documentation. Find production-ready components, templates, and apps — or sell your own code and keep 90%.

    Browse Marketplace →