GSAP vs Framer Motion vs React Spring for Next.js in 2026
Motion ships 67 files carrying a use client directive, GSAP ships zero across 117, and the rename everyone tells you to migrate for turns out to be a 35 byte alias. Measured from the npm registry and the published tarballs.
On this page
Quick answer, September 2026. These three are not three versions of the same decision. Motion and React Spring are MIT React libraries that know what a React Server Component is; GSAP is a framework agnostic animation engine under a custom Webflow licence that does not know Next.js exists. Measured from the published tarballs this week: Motion's React package ships 67 files carrying a use client directive and exposes a dedicated client entry point, while GSAP ships zero across 117 JavaScript files and React Spring ships zero across seven. That single difference decides more App Router architecture than any easing API does. Pick Motion for component and layout animation inside the App Router, GSAP for timeline heavy scroll and canvas work you are happy to quarantine behind your own client boundary, React Spring if you want a small MIT physics model and nothing else.
The three, as actually shipped
Every figure below comes from the npm registry and from the tarballs the registry actually serves, read on 21 September 2026. Nothing here is quoted from a benchmark post.
GSAP 3.15.0, published 13 April 2026. Eighty five stable releases since 2014. Unpacked, the package is 6.26 MB because it ships every plugin in the box.
Motion 13.4.0 and framer-motion 13.4.0, both published 16 September 2026, about a minute apart. More on why that is two packages in a moment.
@react-spring/web 10.1.2, published 24 June 2026. Forty three stable releases, MIT, and a real LICENSE file in the tarball.
The rename is an alias, not a migration
The received wisdom is that Framer Motion was renamed to Motion and that you should migrate off framer-motion. The registry says something more specific, and it changes what you should do about it.
motion@13.4.0 declares exactly two dependencies: tslib and framer-motion@^13.4.0. The dependency runs from motion to framer-motion, not the other way round. Unpack motion and its ECMAScript module entry points are almost empty. dist/es/index.mjs is 35 bytes and reads, in full, export * from 'framer-motion/dom'. The React client entry is 38 bytes. The main React entry is the largest at 721 bytes, and it is a re-export with two local aliases. Ten module entries total 15.4 KB raw, 5.4 KB gzipped.
The implementation is in framer-motion, which itself depends on motion-dom and motion-utils. So the package graph is an alias on top of a facade on top of two implementation packages.
The useful conclusion is the mild one. framer-motion is not deprecated; the registry carries no deprecation notice on it, and the project's own commit on 16 September was titled "Co-locate AnimateView layer animation in framer-motion", which is not what you do to a package you are retiring. Installing motion pulls framer-motion in anyway, and because the re-exports are pure the bundled output is the same after tree shaking. If you are already on framer-motion, there is no migration to perform and no bundle penalty for staying. If you are starting fresh, motion is the name the project promotes. Both are current. What you should not do is rewrite a working codebase on the belief that one of them is going away.
This matters for a second reason: it makes most bundle size charts comparing "Motion" against "Framer Motion" meaningless, because they are measuring the same code twice.
One of these is not open source
GSAP's package.json does not carry an SPDX licence identifier. The field reads, verbatim, Standard 'no charge' license: https://gsap.com/standard-license. The tarball contains no LICENSE file at all. Motion and React Spring both declare MIT, and React Spring ships the licence text.
Read the standard licence rather than the field. It is a custom Webflow licence, not an OSI approved one. Intellectual property remains "the exclusive property of Webflow". It grants a non exclusive worldwide licence for permitted uses including commercial ones. It prohibits using GSAP in "tools that allow users to build visual animations without code that encourages, induces, or materially assists in creating a solution that competes with Webflow's visual animation building capabilities". And it reserves Webflow's right to "update or modify this GSAP License at any time by posting the revised terms".
Now the honest reading, because the alarming one is available and it is not the accurate one.
GSAP really is free, including every plugin that used to sit behind the Club GreenSock paywall. That is a large improvement over the old arrangement and the project's own README says so and links the announcement. The non compete clause is narrow. If you are building a SaaS dashboard, a marketing site or a portfolio, it does not touch you. It bites exactly one category: a no code visual animation builder.
That category is worth calling out here specifically because it is one some readers of this gallery are actually in. If you ship a site builder, a page builder or a template product with a visual animation editor in it, read the clause properly before you take the dependency. For everyone else the practical risk is not the clause, it is the revision right: the terms live at a URL that one company can change unilaterally, and MIT cannot be changed out from under you in the same way. That is a governance property, not a price, and it is the part that stays true regardless of what anything costs next year.
The App Router question, measured
This is the axis that separates them, and it is the one a generic animation comparison never covers.
React Server Components need to know where the client boundary is. A library can declare its own boundary by shipping a use client directive at the top of the modules that need it, which lets you import it from a server component and let the bundler sort it out. We counted the directive across every JavaScript and ECMAScript module file in each tarball.
framer-motion: 67 of 193 files. It also publishes dedicated export subpaths including ./client, ./m and ./mini. It is RSC aware by design.
GSAP: 0 of 117 files. @react-spring/web: 0 of 7 files.
For GSAP the zero is not a defect, it is a consequence. GSAP is framework agnostic and predates RSC by a decade; it has no opinion about React at all. The practical effect is simply that the boundary is your job. Any component that touches gsap needs your own use client at the top, and in an App Router codebase that tends to push you toward a deliberate pattern: a thin client wrapper per animated region rather than animation sprinkled through the tree.
React Spring's zero has the same shape but a smaller blast radius, because its surface area is smaller to begin with.
What you actually ship
These numbers are not directly comparable and pretending otherwise would be the easiest mistake in this piece, so here is what each one means.
GSAP's core is a single file you ship whole: dist/gsap.min.js is 72.9 KB raw and 28.3 KB gzipped. That is the honest core figure. All 25 minified plugin bundles together come to 170.5 KB gzipped, but nobody imports all of them; you add the plugins you use.
React Spring's production ECMAScript modules across its four runtime packages total 21.5 KB gzipped (web 2.2, animated 1.7, core 10.5, shared 7.1). That is close to a whole library figure because the package set is small and stable.
Motion is the one that resists a single number. framer-motion ships 168 module files with sideEffects set to false, so what lands in your bundle depends entirely on what you import. Summing every module gives 104.5 KB gzipped, and that figure is an upper bound rather than a size, because a real build will tree shake across it. The project publishes ./m and ./mini subpaths precisely so you can take a fraction of it. Treat the tree shaking as the feature, not the total as the cost.
The general point: GSAP's cost is roughly fixed and known in advance, Motion's is a function of your imports, React Spring's is small and flat.
The abandoned one is not the one you think
There is a persistent story that React Spring is dead. The commit log says otherwise. pmndrs/react-spring landed real bug fixes on 18 August 2026, not dependency bumps: matching add and remove event listener options in an onScroll cleanup, and parsing negative decimals without a leading integer in a number regex. Version 10.1.2 shipped in June. Its peer range already admits React 19. It is quiet, not abandoned, and quiet is a reasonable state for a library whose physics model has not needed to change.
The genuinely stale package in this comparison is GSAP's own official React integration. @gsap/react sits at 2.1.2, published 15 January 2025. The repository's most recent commit is the same day. That is roughly twenty months without a commit, on the package that provides useGSAP, the hook the documentation tells React users to adopt.
Again, the milder reading is probably the right one. useGSAP is a small hook, 19 KB unpacked, that solves one problem: running GSAP inside React's lifecycle and cleaning up after it. Its peer range is React 17 or newer, so React 19 is already inside it, and a small correct hook can legitimately be finished. But it is worth knowing that the React specific layer of the framework agnostic option is the least actively maintained artefact on this page, while the library everyone calls dead is the one shipping fixes.
motiondivision/motion is the most active of the three by a wide margin, with commits on the day of its most recent release.
How we would choose
Reach for Motion if you are animating React components inside the App Router and want the library to handle its own client boundaries. It is the only one of the three that is RSC aware, its layout and shared element animations have no real equivalent in the other two, and the tree shaking means you can start small. Use whichever of the two package names you prefer and ignore anyone telling you to migrate.
Reach for GSAP when the work is timeline shaped: long scroll sequences, coordinated multi element choreography, canvas and SVG morphing. Nothing here matches its timeline model, and the plugins that used to cost money no longer do. Accept that you are taking a custom licence from a single vendor who can revise it, budget for owning the client boundary yourself, and read the non compete clause if you are building anything that looks like a visual builder.
Reach for React Spring if you want a small MIT dependency with a spring physics model and nothing else in the box. It is the lightest real option at 21.5 KB gzipped, it is genuinely maintained, and it asks the least of your architecture.
We would not mix Motion and GSAP in one codebase without a reason you can name. Both want to own the animation frame, and the debugging cost when they disagree is higher than the convenience that led you there.
If you are wiring up an editor alongside this, the same client boundary question decides that stack too, and we measured it the same way in Tiptap vs Lexical vs Plate.
Written by
Mara LindqvistMara Lindqvist curates the ShipGarden gallery, where we test open-source building blocks so we can own the stack that funds the life.
Frequently asked questions
Which animation library works best with the Next.js App Router?
Motion, because it is the only one of the three that declares its own client boundaries. Its React package ships 67 files carrying a use client directive and publishes a dedicated client export subpath, so you can import it from a server component and let the bundler place the boundary. GSAP ships the directive in zero of its 117 JavaScript files and React Spring in zero of its seven, so with those two the boundary is your responsibility.
Should I migrate from framer-motion to the motion package?
There is nothing to migrate. The motion package declares framer-motion as a dependency, and its module entries are 33 to 721 byte re-exports; the main entry is literally export star from framer-motion slash dom at 35 bytes. framer-motion carries no deprecation notice and is still where the implementation lives. Both names are current and both resolve to the same code after tree shaking, so a working codebase on framer-motion can stay there.
Is GSAP open source now that it is free?
Free and open source are different questions and GSAP is the first without being the second. Its package.json carries no SPDX identifier, the tarball ships no LICENSE file, and the terms are a custom Webflow licence rather than an OSI approved one. It does permit commercial use at no charge including every former Club GreenSock plugin. It also keeps intellectual property with Webflow, prohibits use in tools that compete with Webflow's no code visual animation building, and reserves the right to revise the terms at any time.
Do I need a use client directive for GSAP in Next.js?
Yes. GSAP declares no client boundaries of its own, so any component that imports gsap needs your own use client directive at the top of the file. In practice this pushes App Router codebases toward a thin client wrapper per animated region rather than animation scattered through the component tree. This is a consequence of GSAP being framework agnostic rather than a defect in it.
Is React Spring still maintained in 2026?
Yes. The repository landed substantive bug fixes on 18 August 2026, including an event listener cleanup fix and a number parsing fix for negative decimals, and version 10.1.2 of the web package shipped on 24 June 2026 with React 19 inside its peer range. The more interesting staleness in this comparison is GSAP's own React integration, at sign gsap slash react, whose last release and last commit are both 15 January 2025.
How big are GSAP, Motion and React Spring in a real bundle?
They are not measured the same way. GSAP's core is a single file you ship whole at 28.3 KB gzipped, with plugins added on top. React Spring's four runtime packages total 21.5 KB gzipped in their production module builds. Motion resists one number because framer-motion ships 168 module files with side effects disabled, so summing everything gives 104.5 KB gzipped as an upper bound rather than a real cost; what you actually ship depends on your imports, and the mini and m subpaths exist to take a fraction of it.
More from the garden
Tiptap vs Lexical vs Plate: the Next.js App Router rich text editor decision (2026)
All three are MIT and all three shipped stable releases this month, so maintenance is not the deciding question. Who holds the copyright and what renders on the server is. Measured from the npm registry and the published tarballs.
dnd-kit vs Pragmatic drag and drop vs react-beautiful-dnd for Next.js in 2026
Three React drag and drop libraries, three different stages of life. Read from the npm registry, the published tarballs and the GitHub API on 16 September 2026: one is archived, one is quietly split in two, and one is not a React library at all.
react-hook-form vs TanStack Form vs Formik: the 2026 Next.js comparison
Two of these three repositories were pushed to on the day we ran the check. The third was last pushed 312 days earlier, and the prerelease tag npm still advertises for it was published in December 2020.