Setting up GSAP in Next.js

Setting up GSAP in Next.jsSetting up GSAP in Next.js

Feb 26, 2026 - 8 min

Luka Smiljić

Luka Smiljić

Software Engineer


Getting GSAP to behave itself inside a Next.js app can be a serious headache if you don’t know what you’re doing. If you’ve ever spent days fighting animation glitches on re-renders, then you know exactly what I'm talking about. When aiming for a luxury, high-end look and feel for your client's website, the last things you need is things jumping unexpectedly. Of course, these issues can all be minimised by properly initialising and using GSAP from the start.

Luckily, we’ve done the dirty work for you. Bellow, we'll provide you with a clean starting point you can build on top of so you can focus on the creative side. Plus, with GSAP's pro-tier plugins recently becoming completely free, there has never been a better time to master the library.

What is GSAP and why use it?

First things first, in case you aren’t familiar with GSAP, here's a brief introduction and an explanation on, why here at Workspace, it's our animation library of choice.

While CSS animations work for simple transitions, that approach quickly becomes a maintenance nightmare as complexity grows. Thats why most developers eventually reach for a JavaScript library to simplify the process. Today, the two industry standards are Framer Motion and GSAP. Both are excellent options, and at the end of the day it just comes down to what you prefer and what suits your needs more. So nothing against Motion but GSAP's more imperative control offers a degree of freedom and control you just can't get elsewhere. For this reason we use GSAP whenever we need to create buttery smooth animations. However, this power is a double edged sword because it also means requires a more hands-on approach to the animation lifecycle

Getting started

To get started with GSAP you can check out the docs for more detailed instructions. But in short it's as simple as installing gsap and @react/gsap with your package manager of choice.

You might be wondering what's the deal with that second dependency and why we need when GSAP is platform agnostic? While, yes, GSAP is platform agnostic, there a few things to keep in mind when working with it inside a React project. If you have any experience with GSAP coming from the vanilla JS world, you might be used to just adding gsap.to() and targeting the element you want to animate directly and that being that. But in React manual DOM manipulation is usually a big no go that can lead to memory leaks or flashing of unstyled content. Thankfully, GSAP has our backs and provides us with the useGSAP hook inside @gsap/react. It provides automatic cleanup and lifecycle management, ensuring your animations don't fight with React's Virtual DOM. For more information, again, the docs are your best friend.

The setup

Rather than registering plugins in every individual component, it's best to have your setup centralised all in one place. That way everything’s nice and organised and you can also ensure consistency and easier maintenance across your whole project. In a Next.js, App Router project, we typically centralise our GSAP configuration in a global provider inside a providers.tsx file placed inside the app directory. Depending on your file structure you can of course tweak this to suit your needs.

'use client';

import { PropsWithChildren } from 'react';

import gsap from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';
import { ReactLenis } from '@studio-freight/react-lenis';

gsap.registerPlugin(ScrollTrigger);

const Providers = ({ children }: PropsWithChildren) => {
  return (
    <ReactLenis root>
      {children}
    </ReactLenis>
  );
};

export default Providers;

You’ll notice we’ve wrapped our children with ReactLenis. We've included that as bonus to show how easy it is to add in smooth scrolling to your project with this kind of setup. While you, of course, don't need smooth scrolling for GSAP to work if you use a lot scroll based animations it's nice to have. We'll dive deeper into advanced scroll animations in a future post, but setting this up now builds a scalable foundation.

Your first animation

Great, now that we have the setup out of the way, let's dive in and create a simple animation just so we can get a feel for how these things work. For your first animation let’s build a reusable reveal component. We’ll be using Tweens. This is a core GSAP concept. Tweens take care of doing all the animation work. You can think of them as a sort of property setter. You give it objects you want to animate and specify what properties you want animate. For simple animations with no fancy sequencing you can usually get by with just tweens.

'use client';

import { PropsWithChildren, useRef } from 'react';
import gsap from 'gsap';
import { useGSAP } from '@gsap/react';

const SmoothReveal = ({ children }: PropsWithChildren) => {
  const containerRef = useRef<HTMLDivElement>(null);

  useGSAP(() => {
    // Initial state (invisible and slightly offset)
    gsap.set(containerRef.current, {
      y: 30,
      autoAlpha: 0,
    });

    // The "Tween": Animating to the final state
    gsap.to(container.current, {
      y: 0,
      autoAlpha: 1,
      duration: 1,
      ease: 'power3.out',
    });
  });

  return <div ref={containerRef}>{children}</div>;
};

export default SmoothReveal;

First we create a reference to the DOM element we're animating with useRef and assign it to the element. Next inside the useGSAP hook we define our animation. We use the set method to set the starting appearance of our element. Then we use to and declare what the endpoint of our animation looks like or what we’re animating to.

One thing to point out is we use autoAlpha instead of opacity because it toggles visibility: hidden automatically, which improves performance and prevents users from interacting with "invisible" elements before the animation finishes. To prevent content from flashing before the JavaScript loads, you should also set your main wrapper to visibility: hidden in your CSS.

Wrapping Up

We're all set! You now have a scalable foundation for animations in Next.js. By centralizing your configuration and leveraging the @gsap/react hook for lifecycle management you’ve eliminated the vast majority of common React animation bugs. Experiment with creating your own animations, play with animating various properties, break things, fix them them and then break them again. The best way to really learn these things is to get your hands dirty.

We have planned more GSAP related guides where we'll delve deeper into more complex topics so keep an eye out for that. In the meantime, you might want to check out some of our other blogs for more dev deep dives.

Workspace office background for contact section

Ready to talk?

Send a brief introduction to schedule a discovery call. The call focuses on your challenges and goals and outlines the first steps toward the right digital solution.

Setting up GSAP in Next.js | Workspace