GSAP, Motion or CSS: the decision tree
The question changed: half of what demanded a library is native CSS today. The axes left are license, execution model and what is already native.
- gsap
- motion

Contents
- The right question is not "which library"
- What native CSS already solves on its own
- License: the difference that survives the next release
- Execution model: where each one runs
- Where GSAP is irreplaceable
- Where Motion wins
- The same effect, written three times
- Accessibility: all three demand work, in different degrees
- The decision tree
- The hidden cost of each choice
- Frequently asked questions
- Sources
Start with CSS. Move to Motion when you need spring physics or layout animation in React. Move to GSAP when you need to orchestrate a sequence with several coordinated stages.
That order inverts the common practice, which is choosing the library first and using CSS for whatever is left. And it changed for three reasons that happened in the last two years, not out of preference.
The right question is not "which library"
"GSAP or Framer Motion" was the right question in 2024. Today it skips the decision that comes first: do you need a library?
Three things changed and none of them got announced together.
CSS entered the contest. Scroll-driven animations reached Chrome 115 in July 2023 and Safari 26 in September 2025. Same-document View Transitions became Baseline with Firefox 144. Together, they cover most of the decorative motion people used to build with a library.
GSAP became free, and it became no open source. Since 30 April 2025 it costs nothing, every plugin that used to cost money included. The license, though, is proprietary, called "No Charge": Webflow holds all the intellectual property and a clause forbids use in a tool competing with its visual builder.
Motion took on the name and the license. Once known as Framer Motion, today imported from motion/react, and MIT confirmed in the official repository.
The result is that today's decision axes are what is already native, which license you accept and how each one executes, rather than which one makes the prettiest animation.
What native CSS already solves on its own
Start here, because what CSS solves needs no dependency.
| Effect | Needs a library? | With what |
|---|---|---|
| Reveal on entering the viewport | No | animation-timeline: view() |
| Simple parallax | No | animation-timeline: scroll() |
| Reading progress bar | No | animation-timeline: scroll(y root) |
| Transition between states on the same page | No | document.startViewTransition() |
| Transition between pages | No | The @view-transition at-rule |
| Hover, focus, microinteraction | No | transition |
| Sequence with coordinated stages | Yes | GSAP |
| Section pinning with scrub | Yes | GSAP + ScrollTrigger |
| SVG shape morph | Yes | GSAP + MorphSVG |
| Layout animation in React | Yes | Motion |
| Spring physics | Yes | Motion or GSAP |
One structural advantage tends to decide it: scroll-driven animations run on the compositor thread, off the main thread. They stay smooth while the rest of the page is stuck, which is the exact moment the JavaScript version stutters.
The usual caveat: not every property goes to the compositor. opacity and transform live there; width, height and top force layout and hand the problem back.
The support details and the fallback pattern sit in CSS scroll-driven: what you can use with no JS.
License: the difference that survives the next release
This axis appears in no feature comparison and it is the only one an update never changes.
| GSAP | Motion | |
|---|---|---|
| License | "No Charge", proprietary | MIT |
| Cost | Zero | Zero |
| Intellectual property | Webflow | Community |
| Prohibited use | A tool competing with Webflow's visual builder | None |
| Redistribution | Grants use, not redistribution | Allowed |
| Legal fork | Uncertain | Allowed |
For almost everyone, GSAP's clause is irrelevant, since it targets visual animation builders rather than software development in general. A client site, a SaaS, a portfolio and an e-commerce fall outside it.
But the axis stays real for two profiles: whoever builds a tool in the no-code space, and whoever needs a guarantee of being able to fork the dependency if the maintainer changes course. In those cases, MIT is no legal detail, it is an architecture requirement.
The full license analysis sits in GSAP for free: what the license allows and what it does not.
Execution model: where each one runs
Three different approaches, and the difference shows up once the page takes on load.
CSS with scroll-driven animations runs on the compositor thread. It is the only one of the three that leaves the main thread by default.
Motion describes itself as a hybrid engine: JavaScript combined with native browser APIs, with the declared goal of GPU-accelerated animation at 120fps. In practice, it hands the browser whatever the browser can handle and takes control where it has to.
GSAP is orchestration in JavaScript. It runs on the main thread and computes the values on each frame. That is what gives it fine timeline control, and it is also what makes it sensitive to a busy page.
The practical reading:
| Scenario | Who suffers least |
|---|---|
| Light page, simple animation | A tie |
| Heavy page with React hydration | CSS scroll-driven |
| Animation that has to react to state | Motion |
| Long sequence with control per stage | GSAP, with the main thread caveat |
It is no quality ranking. It is where the work happens.
Where GSAP is irreplaceable
Four cases where no native alternative comes close.
A timeline with coordinated stages. Animating six elements in sequence, with controlled overlap and different easing per segment, is what GSAP's timeline does and what CSS has no structure to express.
Pinning with scrub. Fixing a section and advancing the animation with the scroll is the technique holding up close to every premium agency site. ScrollTrigger has no equivalent, and it was never a paid plugin, contrary to what plenty of texts keep repeating. The eight patterns that cover almost all of its use have their own post, with the minimal code for each.
SVG shape morph. Turning one shape into another. MorphSVG, free today, solves what CSS leaves unsolved.
Text splitting with precise stagger. SplitText breaks text into lines, words or characters and delivers the elements ready to animate in sequence. Free since 2025 too.
The last two sat behind a subscription until April 2025, which changed the arithmetic for a small budget a lot.
Seeing how that shows up together on a real site is worth it: the motion patterns I reverse-engineered on agency sites use almost all of those features together.
Where Motion wins
Two cases, and both are specific to React.
Layout animation. When an element changes position because the layout changed (an item leaving a list, a card reordering, an element switching containers), Motion animates the transition on its own. Doing it by hand demands measuring positions before and after and interpolating between them. It is the problem GSAP's Flip also solves, with the difference that in Motion it is declarative and integrated into React's cycle.
Spring physics. A spring animation has no fixed duration: it has stiffness, damping and mass. The result feels more natural in direct interaction, such as dragging, releasing and elastic snapback. CSS has linear() for approximating complex curves, and it simulates no physics.
Add the MIT license and the idiomatic fit in React, and Motion becomes the default choice for interface, leaving GSAP for narrative motion.
The same effect, written three times
A reveal on entering the viewport, the most common effect in the repertoire. Compare the cost of each approach.
CSS, with no dependency:
.card { opacity: 1; translate: none; }
@supports (animation-timeline: view()) {
.card {
animation: reveal linear both;
animation-timeline: view();
animation-range: entry 10% cover 35%;
}
@keyframes reveal {
from { opacity: 0; translate: 0 1.5rem; }
to { opacity: 1; translate: 0 0; }
}
}Motion, in React:
import { motion } from 'motion/react'
<motion.div
initial={{ opacity: 0, y: 24 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true, amount: 0.3 }}
transition={{ duration: 0.5 }}
>
{content}
</motion.div>GSAP, with ScrollTrigger:
import { gsap } from 'gsap'
import { ScrollTrigger } from 'gsap/ScrollTrigger'
gsap.registerPlugin(ScrollTrigger)
gsap.from('.card', {
opacity: 0,
y: 24,
duration: 0.5,
scrollTrigger: { trigger: '.card', start: 'top 85%' },
})All three produce the same visual result. The differences sit outside the code:
| CSS | Motion | GSAP | |
|---|---|---|---|
| Dependency | None | React bundle | Core + plugin |
| Where it executes | Compositor thread | Hybrid | Main thread |
| Degradation with no support | Content visible, no animation | Not applicable | Not applicable |
| Reversible on scrolling up | Yes, by nature | Configurable | Configurable |
Note the degradation row. It is the only one where the CSS version depends on your having written the right @supports, and the only one where the effect disappears on its own in an engine without support, instead of breaking.
Accessibility: all three demand work, in different degrees
prefers-reduced-motion is automatic in none of the three, and the effort differs.
CSS is the cheapest: one media query covers everything you wrote.
@media (prefers-reduced-motion: reduce) {
.card { animation: none; opacity: 1; translate: none; }
}Motion and GSAP demand a check in JavaScript and a decision per animation. In both cases you have to read the preference and branch, since no global switch exists.
One distinction that seldom appears is worth making: not all movement carries the same risk. A directional slide crossing the viewport is the most common trigger of motion sensitivity. Crossfade, morph and an opacity reveal carry far less risk, because they affect a small area or depend on opacity instead of position.
The crude approach, meaning zeroing every duration, beats ignoring the preference, and it loses to the refined one, which preserves opacity and removes the positional displacement alone.
That is an editorial decision, not a technical one, and the chosen library changes it in no way.
The decision tree
Four questions, in order.
Note that CSS appears twice, at the start and at the end. That is deliberate: under doubt, the answer is CSS, because it is the only option with no maintenance cost, no license to read and no bundle to load.
And all three coexist. The rule I follow on a project: CSS for the decorative and reversible, Motion for reactive interface in React, GSAP for orchestrated narrative. That way each library stays where it is irreplaceable, and the rest of the site depends on it in no way.
The hidden cost of each choice
No decision is free.
Choosing CSS costs browser support. Scroll-driven runs in no stable Firefox, and cross-document View Transitions the same. It degrades well if you write the right fallback, and it makes content disappear if you skip it.
Choosing Motion costs bundle size and coupling to React. It also costs the dependency on a single maintainer, MIT or not, since the license guarantees your right to fork, not that anyone will maintain it.
Choosing GSAP costs main thread and vendor concentration. The most used animation library on the web belongs to one company, with a proprietary license that grants use rather than redistribution.
And choosing all three costs the worst of all: three different ways of doing the same thing in the same project, with nobody remembering which to use where. If you have no written rule for when to use each one, the odds are you have all three doing the work CSS solved.
The text case has a tree of its own, because half the typographic effects need no library at all: see text animation.
Frequently asked questions
Did GSAP go obsolete now that CSS does scroll?
No. CSS covered the decorative motion, meaning reveal, parallax and progress. A timeline with coordinated stages, pinning with scrub and SVG morph still have no native equivalent. The share is what changed: half of what demanded GSAP two years ago demands it no longer.
Motion or GSAP for a React project?
It depends on the kind of animation. A reactive interface, a layout that reorders and spring physics go better in Motion, which is MIT and idiomatic in React. Narrative motion, with a coordinated sequence and scroll scrubbing, goes better in GSAP. The two coexist in the same project with no conflict.
Does GSAP's license stop me from using it in a commercial product?
No. The clause targets tools that build animation through a visual interface and compete with Webflow on that point. A client site, a SaaS using GSAP in its own interface, a portfolio and an e-commerce fall outside the reach. If you build a visual animation editor, then seeking written consent pays off.
Can CSS scroll-driven and GSAP be used in the same project?
They can, and it is the combination I would recommend. CSS for what is simple and reversible, GSAP where orchestration exists. The caution is having a written rule for which to use where, or the project accumulates two solutions to the same problem.
Sources
- GSAP — Licensing. "No Charge" license, effective 30 April 2025. Accessed 20 August 2026.
- GSAP — Plugins. Accessed 20 August 2026.
- Motion — Official repository. MIT license. Accessed 20 August 2026.
- Motion — Documentation. Accessed 20 August 2026.
- MDN — CSS scroll-driven animations. Accessed 19 August 2026.
- MDN — View Transition API. Accessed 20 August 2026.
- WebKit — WebKit Features for Safari 26.5. Accessed 20 August 2026.
Verified on 20 August 2026.
Review trigger: revisit when (a) Firefox enables scroll-driven animations in the stable release, which changes the tree's first question, (b) GSAP's license changes, (c) CSS gains a spring physics primitive, or (d) any of the three changes its execution model.
Read next
Motion •
Motion Design for the Web: The Complete Guide
Scroll, text, images and video: the complete catalog of motion techniques for the web, with implementation in Next.js and the cases where each one pays off.
- motion
- scroll
The definitive guide — a Next.js site built around motion and scroll
The scroll foundation that, when missing, keeps the animations from working at all: Lenis, GSAP and Next.js wired in the right order and the mistakes to avoid.
- next.js
- lenis
Infra •
Documentation: deploying a Next.js application with GitHub + Hostinger
Every push becomes a live site with no hosting panel involved: connecting GitHub to Hostinger, the build settings that break and the checks after each deploy.
- deploy
- github


