Component Animation Using GSAP
How to create smooth, performant component animations using the GreenSock Animation Platform.
Animations add a different character to your website. They make your websites feel alive, guide user attention, and add subtle polish that separates a good website from a great one.
GSAP is a library that lets you create complex and highly customizable animations.
In this tutorial, we'll try some animations and start learning GSAP with Next.js. At the end of the tutorial, we'll be making a component animation demo.

First of all, make sure you install GSAP:
npm install gsapshell
Import this at the top of the file, and use Next.js App Router with "use client" for us to run effects in the browser:
"use client" import {useEffect, useRef} from "react"; import gsap from "gsap";typescript
Use the useRef hook to target a specific DOM node:
const textRef = useRef<HTMLHeadingElement>(null);typescript
gsap.fromTo takes the initial state and the final state of an element, then smoothly transitions between the two:
useEffect(()=>{ if(textRef.current){ gsap.fromTo( textRef.current, {y:100, opacity:0}, {y:0, opacity:1, duration:1, ease:"power2.inOut"} ) } },[]);typescript
gsap.fromTo requires the following arguments:
- Target → textRef.current (the DOM element you are targeting).
- From state → { y: 100, opacity: 0 } — element starts 100px lower and is invisible.
- To state → { y: 0, opacity: 1, duration: 1, ease: "power2.inOut" } — moves to original position, fades in, takes 1 second.
You can read more about easing at: https://gsap.com/docs/v3/Eases/
Finally, add this to your component:
<h1 ref={textRef} className="text-4xl font-medium"> Hello World from GSAP. </h1>typescript
Here comes the best part — you can add this animation to any component now.
For instance, to add a similar animation to an image component, make an imageRef:
const imageRef = useRef<HTMLDivElement>(null);typescript
Here is a full working example:
"use client"; import { useEffect, useRef } from "react"; import gsap from "gsap"; import Image from "next/image"; export default function GsapDemo() { const textRef = useRef<HTMLHeadingElement>(null); const imageRef = useRef<HTMLDivElement>(null); useEffect(() => { if (textRef.current) { gsap.fromTo( textRef.current, { y: 100, opacity: 0 }, { y: 0, opacity: 1, duration: 1, ease: "power2.inOut" } ); } if (imageRef.current) { gsap.fromTo( imageRef.current, { y: 50, opacity: 0, scale: 0.8 }, { y: 0, opacity: 1, scale: 1, duration: 1, ease: "power2.out", delay: 0.5 } ); } }, []); return ( <div className="flex flex-col items-center justify-center min-h-screen bg-white"> <h1 ref={textRef} className="text-4xl font-medium mb-6 text-black"> Hello World from GSAP </h1> <div ref={imageRef}> <Image src="/next.svg" alt="Next.js Logo" width={200} height={200} /> </div> </div> ); }typescript