GSAP (GreenSock Animation Platform) is a JavaScript library built to animate pretty much anything code can touch: CSS, SVG, canvas, WebGL, and plain JavaScript objects. Since April 30, 2025, it has been completely free, including every plugin, thanks to sponsorship from Webflow.
What is GSAP
GSAP is an animation engine that runs on top of any framework and in any modern browser. Instead of hand-rolling CSS transitions and requestAnimationFrame loops, you describe animations declaratively, and the library handles timing, easing, and performance under the hood.
Three reasons GSAP has stayed the top animation tool on the web for over 15 years:
Consistent behavior across browsers, including tricky edge cases with SVG and transforms.
Precise control over animation sequencing through timelines.
A rich plugin ecosystem covering scroll effects, shape morphing, text splitting, and drag interactions.
Some of these plugins used to sit behind a paid Club membership. Now the entire toolkit is open and cleared for commercial use.
Key features
gsap.to() / from() / fromTo() — the core tweens that animate properties from one value to another.
Timeline — combines animations into a controllable sequence with pauses and overlaps.
Easing — shapes the character of motion: spring, bounce, smooth deceleration.
stagger — triggers animations one after another across a list of elements.
gsap.matchMedia() — lets you run different animations per breakpoint and respect prefers-reduced-motion.
ScrollTrigger — ties animations to scroll position: reveals, pinning, parallax, scrubbing.
SplitText — breaks text into lines, words, and characters for granular animation.
Flip — smoothly animates the transition between two layout states.
Draggable — drag interactions with inertia and grid snapping.
Installation and setup
Quick start via CDN:
<script src="https://cdn.jsdelivr.net/npm/gsap@3/dist/gsap.min.js"></script> <script> gsap.to(".box", { x: 300, duration: 1, ease: "power2.out" }); </script>
Installing via npm:
npm install gsap
import gsap from "gsap" gsap.to(".box", { rotation: 360, duration: 2 })
Registering plugins: plugins are imported separately and registered once at app startup.
import gsap from "gsap" import { ScrollTrigger } from "gsap/ScrollTrigger" gsap.registerPlugin(ScrollTrigger)
If a plugin's animation silently fails to run, the first thing to check is whether you called gsap.registerPlugin(). It's the most common culprit.
Integration with React
In React, animations need to start after mounting and clean up on unmount. GSAP provides an official package, @gsap/react, with a useGSAP() hook for exactly this.
npm install gsap @gsap/react
The useGSAP hook works similarly to useEffect, but it automatically tracks every animation you create and cleans them up when the component unmounts. No manual cleanup code needed.
import { useRef } from "react" import gsap from "gsap" import { useGSAP } from "@gsap/react" gsap.registerPlugin(useGSAP) function Hero() { const container = useRef() useGSAP( () => { gsap.from(".title", { y: 40, opacity: 0, duration: 0.8, ease: "power2.out" }) gsap.from(".subtitle", { y: 20, opacity: 0, duration: 0.6, delay: 0.2 }) }, { scope: container } ) return ( <section ref={container}> <h1 className="title">Headline</h1> <p className="subtitle">Subheadline</p> </section> ) }
Why scope matters: the scope parameter restricts selectors (.title, .subtitle) to within the container. This way, one component's animation won't accidentally hit similarly named classes elsewhere on the page.
Using ScrollTrigger inside a component:
import { useRef } from "react" import gsap from "gsap" import { ScrollTrigger } from "gsap/ScrollTrigger" import { useGSAP } from "@gsap/react" gsap.registerPlugin(ScrollTrigger, useGSAP) function Features() { const container = useRef() useGSAP( () => { gsap.from(".card", { y: 60, opacity: 0, stagger: 0.15, scrollTrigger: { trigger: ".cards", start: "top 80%" }, }) }, { scope: container } ) return ( <div ref={container}> <div className="cards"> <div className="card">1</div> <div className="card">2</div> <div className="card">3</div> </div> </div> ) }
In Next.js and other SSR frameworks, keep the ScrollTrigger import and animation logic inside a client component. useGSAP runs after mounting, so DOM access within it is safe.
Pricing and licensing
Since April 30, 2025, GSAP has been free for everyone, including the entire set of previously paid plugins and commercial use. A separate subscription is no longer required.
One licensing restriction remains: GSAP cannot be embedded into products that compete with Webflow's visual builder — meaning you can't build your own no-code animation tool with it. For regular websites, landing pages, and applications, there are no restrictions.
Practical use cases
Revealing blocks on scroll:
gsap.from(".section", { y: 50, opacity: 0, duration: 0.8, scrollTrigger: { trigger: ".section", start: "top 85%" }, })
Pinning a section with parallax:
gsap.to(".bg", { yPercent: -30, ease: "none", scrollTrigger: { trigger: ".hero", start: "top top", end: "bottom top", scrub: true, pin: true, }, })
Animating a headline letter by letter:
import { SplitText } from "gsap/SplitText" gsap.registerPlugin(SplitText) const split = new SplitText(".headline", { type: "chars" }) gsap.from(split.chars, { y: 20, opacity: 0, stagger: 0.03 })
Button micro-interactions:
const btn = document.querySelector(".cta") btn.addEventListener("mouseenter", () => gsap.to(btn, { scale: 1.05, duration: 0.2 })) btn.addEventListener("mouseleave", () => gsap.to(btn, { scale: 1, duration: 0.2 }))
Using GSAP with AI-driven site builders
A growing number of AI agent tools can build, save, and deploy websites, web apps, and dashboards from a written description. For landing pages, this workflow is genuinely useful: you describe the structure and animations in plain language, and the agent assembles and publishes the finished page.
GSAP fits naturally into this kind of process — typically, the library can be loaded with a single tag in the <head>, after which the agent maps animations onto the markup.
A practical workflow looks like this:
Ask the agent to load GSAP and the needed plugins via CDN.
Describe animations section by section, specifying exactly what moves, from where, and with what delay.
Ask for the animation logic to be wrapped in a prefers-reduced-motion check, to respect accessibility settings.
After the page is built, test it on mobile — heavy pin and scrub effects sometimes need to be disabled on narrow screens using gsap.matchMedia().
Example prompt snippet:
Load GSAP and ScrollTrigger via CDN. On the landing page: - hero section: headline and button fade in from below with a 0.2s delay; - features block: cards slide in one by one as they enter 80% of the viewport; - hero background image moves with a parallax effect on scroll. Wrap the animations in matchMedia: disable the parallax effect on screens narrower than 640px.
This approach produces a lively landing page without manually coding every animation: you describe the desired behavior in words, and the agent assembles the finished page.
Common issues and how to fix them
A plugin's animation doesn't fire — gsap.registerPlugin() was never called.
The animation feels jerky — you're animating top/left instead of x/y; transforms run on the GPU and are much smoother.
In React, the animation repeats or breaks during transitions — the logic isn't wrapped in useGSAP(), or scope wasn't set.
ScrollTrigger calculates positions incorrectly — call ScrollTrigger.refresh() after fonts and images finish loading.
The animation interferes with users — prefers-reduced-motion hasn't been handled via gsap.matchMedia().
Resources
Official site: gsap.com
Documentation: gsap.com/docs/v3
ScrollTrigger docs: gsap.com/docs/v3/Plugins/ScrollTrigger
React package: @gsap/react
GitHub: github.com/greensock/GSAP
GSAP is a strong fit for landing pages built with the help of AI agents: a handful of well-placed animations bring a page to life and help guide visitor attention to what matters most.
