Motion (formerly Framer Motion) and GSAP (formerly GreenSock) are two popular JavaScript animation libraries.
Both can create stunning animations, beyond anything achievable with CSS alone. But they have fundamental differences.
This guide compares Motion and GSAP on licensing, features, timelines, bundle size, hardware acceleration and adoption (complete with full comparison tables), to help you decide which is right for your project.
At a glance
| GSAP | Motion | |
|---|---|---|
| Funding | Free Closed source, owned by Webflow | Independent MIT open source |
| Minimum bundle size | 27.29 kB | 3.12 kB |
| Hardware acceleration | Not included | Included |
| Accelerated scroll | Not included | Included |
| Timeline sequencing | Included | Included |
| Mutable timelines | Included | Included |
| Accelerated timelines | Not included | Included |
| Springs | Not included | Included |
| React and Vue APIs | Not included | Included |
| FLIP animations | Included | Included |
| Layout animations | Not included | Included |
| npm monthly downloads | 24 million | 204 million |
Licensing
Motion is fully independent and MIT open source. It's financially supported by a mix of incredible industry-leading sponsors like Framer, Cursor, Linear, Clerk, Figma and Sanity, as well as sales from Motion+.
GSAP, by contrast, is closed source and owned and funded by Webflow. While it can be used for free in many projects, its license contains a critical restriction: You're prohibited from using GSAP in any tool that competes with Webflow. Furthermore, its license states that Webflow can terminate it at its discretion.
With Motion, you have a guarantee of freedom. That MIT license is irrevocable. You will never be forced to remove and replace your animation library because of a business decision made by another company. This provides the stability and peace of mind that professional development teams require.
Motion's independence and self-sufficiency also means we work with a broad base of users and companies, creating a library that works for the whole web, rather than the interests of a single company.
Features
Both libraries are fully featured, and there is plenty of overlap. Each also has unique strengths.
React & Vue APIs
Motion provides a first-class, declarative API that is a natural extension of React and Vue. Animations are defined directly in your components via props, keeping your code clean, readable and easy to maintain.
<motion.div animate={{ x: 100 }} />GSAP, by contrast, uses an imperative model. While it has a useGSAP hook to help integrate into React's lifecycles, it still requires using refs. Mixing its imperative API into React's declarative components leads to more verbose and error-prone code.
const container = useRef()
useGSAP(() => {
gsap.to(".box", { x: 100 })
}, { scope: container })
return (
<div ref={container}>
<div className="box"></div>
</div>
);Motion also features an industry-leading layout animation engine, which goes far beyond the FLIP animations in GSAP. It works in React, Vue and plain JavaScript, with animateLayout().
Timeline sequencing
GSAP is famous for its powerful timeline function, which uses an imperative, chain-based API to build complex animation sequences. It's mature, and an industry standard for good reason.
const tl = gsap.timeline()
tl.to("h1", { opacity: 1 })
tl.to("p", { y: 0 }, "-=0.5")Contrary to popular belief, Motion also provides a modern, declarative alternative. Instead of chain-based commands, animate() accepts a simple array, making it easy to read, modify and dynamically generate timeline sequences.
animate([
["h1", { opacity: 1 }],
["p", { y: 0 }, { at: "-0.5" }]
])This timeline can animate anything the animate() function can, mixing HTML elements, SVG elements, motion values, and even 3D objects from libraries like Three.js - all within the same sequence. Each segment can use springs, and eligible values are hardware accelerated.
GSAP's timeline has long had one big advantage: it's mutable. Once playback has begun, you can add, move and remove its children.
Motion does this too. animate() returns a timeline. You can add segments, labels, callbacks, pauses and other timelines, then move or remove them at any point, including while the timeline plays.
const tl = animate([
["h1", { opacity: 1 }],
["p", { y: 0 }, { at: "-0.5" }]
])
tl.add("outro").add(["h1", { scale: 0.9 }])
tl.call((direction) => console.log(direction), "outro") // 1 or -1
tl.addPause("outro")
tl.playTo("outro")Timeline APIs compared
| GSAP | Motion | |
|---|---|---|
Building | ||
| From and to values | Included | Included |
| Multiple keyframes | Included | Included |
| Springs in a timeline | Not included | Included |
| Nested timelines | Included | Included |
| Play a nested timeline on its own | Included | Not included |
Editing | ||
| Add to an existing timeline | Included | Included |
| Move a segment | Included | Included |
| Remove a segment | Included | Included |
| Clear | Included | Included |
Sequencing | ||
| Absolute and relative positions | Included | Included |
| Start of previous segment | Included | Included |
| Labels | Included | Included |
| Label with offset | Included | Included |
| Percentage offsets | Included | Not included |
| Stagger | Included | Included |
Labels | ||
| Add and remove | Included | Included |
| Time of a label | Included | Included |
| Next, previous and current label | Included | Not included |
Callbacks | ||
| Sequenced callbacks | Included | Included |
| Directionally-aware sequenced callbacks | Not included | Included |
Per-animation onStart, onComplete | Included | Not included |
Timeline onComplete | Included | Included |
onUpdate, onRepeat, onReverseComplete | Included | Included |
Playback | ||
| Play, pause, stop | Included | Included |
| Seek to a time or label | Included | Included |
| Play to a time or label | Included | Included |
| Reverse | Included | Included |
| Progress | Included | Included |
| Speed | Included | Included |
| Repeat and yoyo | Included | Included |
| Current repeat | Included | Not included |
| Promise | Included | Included |
| Scroll scrubbing | Included | Included |
Performance | ||
| Hardware accelerated | Not included | Included |
GSAP still has some timeline features that Motion doesn't, like label navigation, percentage offsets, per-animation callbacks, querying the current repeat, and playing a nested timeline on its own. Where Motion is ahead: springs, hardware acceleration, and callbacks that know the playback direction.
Full feature comparison table
A tick means supported and a cross means not supported. A dash means partial support. A note after a mark gives a size, or says the feature is in Motion+.
| GSAP | animate mini | animate | |
|---|---|---|---|
General | |||
| MIT license | Not included | Included | Included |
| Accelerated animations | Not included | Included | Included |
| React API | Not included | Not included | Included |
| Vue API | Not included | Not included | Included |
| Three.js API | Included | Not included | Included |
| vgpu API | Not included | Not included | Included |
Values | |||
| Individual transforms | Included | Not included | Included |
| Complex transform strings | Included | Included | Included |
| Named colors | Partly included | Included | Not included |
| Color type conversion | Included | Included | Included |
| Wide-gamut colours (oklch, oklab) | Not included | Included | Included |
| To/from CSS variables | Included | Included | Included |
| To/from CSS functions | Partly included | Included | Not included |
| Animate CSS variables | Included | Included | Included |
| Simple keyframe syntax | Included | Included | Included |
| Wildcard keyframes | Not included | Included | Included |
| Relative values | Included | Not included | Not included |
Output | |||
| Element styles | Included | Included | Included |
| Element attributes | Included | Not included | Included |
| Custom animations | Included | Not included | Included |
Options | |||
| Duration | Included | Included | Included |
| Direction | Included | Included | Included |
| Repeat | Included | Included | Included |
| Delay | Included | Included | Included |
| End delay | Included | Not included | Not included |
| Repeat delay | Included | Not included | Included |
Stagger | |||
| Stagger | Included | Included | Included |
| Min delay | Included | Included | Included |
| Ease | Included | Included | Included |
| Stagger origin | Included | Included | Included |
| Edges | Included | Included | Included |
| Random | Included | Included | Included |
| Grid | Included | Included | Included |
Timeline | |||
| Timeline sequences | Included | Not included | Included |
| Mutable timelines | Included | Not included | Included |
| Accelerated timelines | Not included | Not included | Included |
Controls | |||
| Play | Included | Included | Included |
| Pause | Included | Included | Included |
| Finish | Included | Included | Included |
| Reverse | Included | Not included | Included |
| Stop | Included | Included | Included |
| Playback rate | Included | Included | Included |
Easing | |||
| Linear | Included | Included | Included |
| Cubic bezier | Included | Included | Included |
| Steps | Included | Included | Included |
| Spring | Not included | Included(+1.55 kB) | Included |
| Spring physics | Not included | Not included | Included |
| Inertia | Included | Not included | Included |
| Custom easing functions | Included | Included | Included |
Events | |||
| Complete | Included | Included | Included |
| Cancel | Included | Included | Included |
| Start | Included | Not included | Included |
| Update | Included | Not included | Included |
| Repeat | Included | Not included | Included |
Path | |||
| Motion path | Included(+8.59 kB) | Included | Included |
| Path morphing | Included(+8.72 kB) | Not included | Included |
| Path drawing | Included | Included | Included |
Scroll | |||
| Scroll trigger | Included(+16.88 kB) | Included | Included |
| Scroll-linked animations | Included(+16.88 kB) | Included | Included |
| Hardware accelerated animations | Not included | Included | Included |
Gestures | |||
| Drag | Included(+12.29 kB) | Not included | Included(+8.31 kB) |
Layout | |||
| FLIP animations | Included(+8.53 kB) | Not included | Included |
| Layout animations | Not included | Not included | Included |
| Transform-only layout | Not included | Not included | Included |
| View animations | Not included | Not included | Included |
Extra Features | |||
| AnimateNumber | Not included | IncludedReact and Vue, Motion+ | IncludedReact and Vue, Motion+ |
| Cursor | Not included | IncludedReact and Vue, Motion+ | IncludedReact and Vue, Motion+ |
| Split Text | Included | IncludedMotion+ | IncludedMotion+ |
| Ticker | Not included | IncludedReact and Vue, Motion+ | IncludedReact and Vue, Motion+ |
| Typewriter | Not included | IncludedMotion+ | IncludedMotion+ |
Bundle size
Motion is built with a modern, modular architecture. If your bundler supports tree-shaking (like Vite, Rollup or Webpack), you only ever include the code you actually use. GSAP's older architecture, by contrast, means that importing any part of the core includes all of it.
This, combined with Motion's focus on leveraging native browser APIs, results in a significantly smaller footprint.
GSAP has no built-in springs, so the springs group shows Motion only. The GSAP scroll and drag bundles are the core plus ScrollTrigger or Draggable.
A smaller bundle means a faster site load and a better user experience, especially on mobile devices. With Motion, you can deliver stunning animations with a minimal performance cost.
Hardware acceleration
You might already know that for best animation performance you should stick to animating opacity, transform, filter and clipPath, because these styles can be rendered entirely on the GPU.
But when animating with Motion, these values can enjoy an extra performance boost using "hardware accelerated" animations. Motion runs eligible animations via the Web Animations API (WAAPI), so the animations themselves run on the compositor - separate from the JavaScript running on your CPU.
This means if your website or app is performing heavy work, animations remain smooth. GSAP runs every animation on the main thread, so it will pause and stutter when the main thread is busy.
Motion accelerates in many situations:
- Independent transforms like
x,y,scaleandrotate, even when they're split across several animations on one element. - Mixed values. In
animate(element, { width: 100, x: 100 }),xruns via WAAPI whilewidthruns on the main thread. - Timelines. Eligible values in a timeline sequence stay accelerated.
- Interruptions. Speed changes, seeking and interruptions keep animations accelerated where possible.
Motion can even perform hardware accelerated scroll animations. Because browsers render all scroll on the GPU, JS-based scroll animations are always slightly out-of-sync. Not so with Motion.
const animation = animate(element, { opacity: [0, 1] })
scroll(animation)Start-up time
To animate between any two values, they have to be mixable. Think, two numbers, or two colors. But what if we want to perform an animation where we don't even know the initial value? Or we do - but it's a value like height: auto, or a color defined in a CSS variable like var(--my-color)?
To make these values mixable, the library first needs to measure them. But measuring something that's just been rendered forces a layout or style calculation. These are slow.
To solve this, Motion introduced deferred keyframe resolution. This ensures we batch all measurements into a single operation, drastically reducing style and layout calculations.
In benchmarks, Motion is 2.5x faster than GSAP at animating from unknown values, and 6x faster at animating between different value types.

This is great for user experience, and also great for performance scores like Interaction to Next Paint (INP).
Adoption
It's also helpful to see what other developers are choosing. For modern applications, npm is a great measure of a library's adoption and momentum.
Here, the numbers are clear: Motion is the most-used animation library in the ecosystem. It reached 47.2 million weekly npm downloads in the seven days ending 2 September 2026. The chart compares framer-motion, react-spring, gsap, and animejs over the same period.
January 2021 to 2 September 2026
Smoothed quarterly trends. Endpoints show actual weekly totals.
Source: npm download API. Motion uses framer-motion. All four series end on 2 September 2026.
Conclusion
Both Motion and GSAP are powerful, production-ready libraries capable of creating stunning, award-winning animations. The best choice depends entirely on the priorities of your project and team.
When to use Motion?
You should choose Motion if your priority is overall performance, a smaller bundle size, and a modern developer experience. Hardware acceleration by default, springs, mutable timelines, layout animations, first-class React and Vue support and a truly open-source MIT license make it the definitive choice for building fast, modern web applications. With Motion+, you also get a much larger selection of ready-made components for React and Vue, like AnimateNumber, Ticker and Cursor, plus 520+ examples.
When to use GSAP?
You might still prefer GSAP if you want every plugin for free (it's backed by Webflow, a large corporation), you need the timeline features Motion doesn't have yet, like label navigation and percentage offsets, or your team already knows GSAP's API.