Motion & Animation

GSAP

GSAP is the animation library behind polished, scroll-driven web experiences. Timelines, easing and ScrollTrigger give you frame-perfect control without fighting CSS.

advanced13 min readUpdated Sep 15, 2026
hero.js
js
// hero.js
import gsap from "gsap";

const tl = gsap.timeline({ defaults: { ease: "power2.out" } });

tl.from(".hero h1", { y: 40, opacity: 0, duration: 0.6 })
  .from(".hero p", { y: 20, opacity: 0, duration: 0.4 }, "-=0.3")
  .from(".hero button", { scale: 0.9, opacity: 0 }, "-=0.2");
Core
Free and open source
Tweens
gsap.to, from, fromTo
Timelines
gsap.timeline
Scroll
ScrollTrigger plugin
Performance
Animate transforms and opacity
React
useGSAP hook

Why it matters

Why reach for GSAP

Precise control

Timelines, easing, labels and position parameters let you choreograph complex sequences exactly.

Performant by default

GSAP animates transforms and opacity efficiently and uses requestAnimationFrame, keeping motion smooth.

Scroll and beyond

ScrollTrigger and other plugins tie animation to scroll, pinning, snapping and real-time interaction.

The big picture

The three ideas behind GSAP

Tweens change values over time, timelines sequence them, and plugins extend the system to scroll and beyond.

Tweens

Animate

Change one or more properties over a duration with easing.

Timelines

Sequence

Compose tweens on a shared timeline with precise timing and labels.

Plugins

Extend

ScrollTrigger, Flip, Draggable and others add scroll, layout and interaction features.

GSAP at a glance

The core of GSAP

gsap.to

Animate to a target value, the most common call.

gsap.from and fromTo

Animate from a value, or between two explicit values.

Timelines

Sequence tweens with position parameters and labels.

Stagger

Offset animations across a list of targets.

ScrollTrigger

Drive animation from scroll position, with pinning and snapping.

Performance

Stick to transform and opacity, and clean up on unmount.

A short history

From Flash's successor to the web standard

  1. 2008

    GSAP released

    GreenSock's animation platform offers precise, timeline-based control.

    08
  2. 2014

    TweenLite and TweenMax

    The library becomes the de facto standard for complex web animation.

    14
  3. 2020

    ScrollTrigger

    Scroll-driven animation becomes accessible without custom scroll math.

    20
  4. 2023

    GSAP goes fully free

    All plugins, including previously paid ones, become free to use.

    23
  5. Today

    The motion standard

    Used for marketing sites, product tours, data storytelling and games.

    Today

The complete guide

GSAP: Everything you need to know

Why reach for GSAP?

CSS handles simple transitions and keyframes well, and for a hover effect or a fade-in it is the right tool. The moment you need to coordinate several elements, tie animation to scroll, or control playback dynamically, CSS becomes awkward. That is where GSAP (GreenSock Animation Platform) shines.

GSAP gives you a small, expressive API for animating values over time, and a timeline model for sequencing them. It runs on requestAnimationFrame, animates efficiently, and its plugin ecosystem covers scrolling, dragging, morphing and more. For polished marketing sites, product tours and data storytelling, it is the standard.

Tweens

A tween changes one or more properties over a duration.

// tweens.js
import gsap from "gsap";

gsap.to(".box", { x: 200, duration: 1, ease: "power2.out" });
gsap.from(".title", { y: 40, opacity: 0, duration: 0.8 });
gsap.fromTo(".card", { scale: 0.8 }, { scale: 1, duration: 0.4 });

to animates to a value, from animates from a value to the current state, and fromTo specifies both. GSAP handles transforms (x, y, scale, rotation) natively, which are the properties that stay on the compositor and keep animation smooth.

Timelines

A timeline sequences tweens on a shared clock, with position parameters that make timing precise.

// timeline.js
const tl = gsap.timeline({ defaults: { ease: "power3.out" } });

tl.from(".nav", { y: -20, opacity: 0 })
  .from(".hero h1", { y: 40, opacity: 0 }, "-=0.3")
  .from(".hero p", { y: 20, opacity: 0 }, "-=0.2")
  .from(".hero button", { scale: 0.9, opacity: 0 }, "-=0.2");

The "-=0.3" means “start 0.3 seconds before the previous tween ends”, which overlaps steps for a natural flow. Timelines can be paused, reversed, sped up, seeked and labelled, which makes them far more controllable than a chain of setTimeout calls. They also make cleanup trivial: kill the timeline and every tween stops.

Stagger and easing

Stagger offsets the same animation across many targets, which is the key to the polished list and grid effects you see on modern sites.

// stagger.js
gsap.from(".card", {
  y: 30,
  opacity: 0,
  duration: 0.5,
  stagger: 0.08,
});

Easing controls the feel. power2.out starts fast and settles, back.out overshoots slightly, and elastic bounces. GSAP’s easing is one of its strengths and is hard to match with CSS alone.

ScrollTrigger

ScrollTrigger ties animation to scroll position, enabling the scroll-driven storytelling that defines many award-winning sites.

// scroll.js
import gsap from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";

gsap.registerPlugin(ScrollTrigger);

gsap.to(".panel", {
  xPercent: -100,
  ease: "none",
  scrollTrigger: {
    trigger: ".panels",
    start: "top top",
    end: "+=2000",
    scrub: true,
    pin: true,
  },
});

scrub: true links the animation progress to the scrollbar, and pin: true holds the section in place while scrolling. ScrollTrigger also supports snap, toggles and callbacks, and handles resizing and refresh for you.

Performance

Motion should feel effortless, and that means animating the right properties.

  • Animate transform and opacity, which the compositor can handle without layout.
  • Avoid animating width, height, top, left or margin, which force layout every frame.
  • Animate fewer elements at once, and pause offscreen animations.
  • Use will-change sparingly on elements that are about to animate.
  • Kill timelines when a component unmounts to avoid leaks and wasted work.

See the Web Performance guide for how animation interacts with metrics like INP.

React and cleanup

The official useGSAP hook from @gsap/react scopes selectors to a container and cleans up automatically, which avoids the common pitfalls of animating React-managed DOM.

// Hero.jsx
import { useRef } from "react";
import { useGSAP } from "@gsap/react";
import gsap from "gsap";

export function Hero() {
  const ref = useRef(null);

  useGSAP(() => {
    gsap.from(".title", { y: 40, opacity: 0 });
  }, { scope: ref });

  return <section ref={ref}><h1 className="title">Hello</h1></section>;
}

The hook handles StrictMode’s double invocation and reverts animations on unmount, so you do not leak tweens or leave elements in a half-animated state.

Accessibility

Always respect prefers-reduced-motion. For users with motion sensitivity, replace movement with a simple fade or skip the animation entirely.

// reduced.js
const mm = gsap.matchMedia();

mm.add("(prefers-reduced-motion: no-preference)", () => {
  gsap.from(".card", { y: 30, opacity: 0, stagger: 0.08 });
});

mm.add("(prefers-reduced-motion: reduce)", () => {
  gsap.from(".card", { opacity: 0 });
});

This is a small amount of code that makes a real difference for a meaningful group of users.

Best practices

  • Use timelines instead of chained timeouts for any sequence.
  • Animate transform and opacity, not layout properties.
  • Stagger lists for a polished, natural feel.
  • Register plugins once and reuse them.
  • Clean up timelines on unmount, especially in React.
  • Respect prefers-reduced-motion.
  • Pause or kill offscreen animations.

Common mistakes

  • Animating layout properties and causing jank.
  • Chaining setTimeout calls that drift and are hard to cancel.
  • Leaving timelines running after a component unmounts.
  • Overusing motion until the page feels busy.
  • Ignoring reduced-motion preferences.
  • Running heavy scroll animations on low-powered devices without testing.

Where to go next

GSAP turns animation from a chore into a design tool. Start with the CSS animations baseline so you know when you need more, then add GSAP for sequencing and scroll. Pair it with Three.js for 3D scenes and keep an eye on the metrics in the Web Performance guide. Then animate one hero section and feel the difference a well-timed sequence makes.

Animating properties

Transform and opacity can be animated on the compositor. Animating width, top or margin triggers layout on every frame.

Prefer
gsap.to(".card", {
  x: 100,
  scale: 1.05,
  opacity: 0.8,
  duration: 0.4,
});
Avoid
gsap.to(".card", {
  left: 100,
  width: 320,
  marginTop: 20,
  duration: 0.4,
});

Sequencing animation

A timeline manages timing, easing and cleanup together. Chained timeouts drift and are hard to cancel.

Prefer
const tl = gsap.timeline();
tl.to(".a", { x: 100 })
  .to(".b", { y: 50 }, "-=0.2")
  .to(".c", { opacity: 1 });
Avoid
setTimeout(() => {
  gsap.to(".a", { x: 100 });
  setTimeout(() => {
    gsap.to(".b", { y: 50 });
  }, 300);
}, 300);

FAQ

Frequently asked questions

Keep learning

Related topics from the roadmap.

$ start learning

Ready to start learning Advanced Animation?

Our interactive tutorial walks you through Advanced Animation step by step — with quizzes and real code you can run in the browser.