Integrating GSAP Animations into React: A Codex Website Case Study
This guide documents the process of enhancing the Codex Website(https://www.codex-cmr.com/) with modern, engaging animations using GSAP (GreenSock Animation Platform) and React.
Table of Content
- Inspiration and Motivation
- Technical Stack
- Implementation Process
- Core Animation Template
- Key React Concepts for Animations
- Summary
Inspiration and Motivation
The idea to add animations emerged from exploring premium award-winning websites on:
Here , I came across two websites that particularly stood out for their harmonious color palettes and captivating animations:
These examples demonstrated how thoughtful animation can create beautiful, tasteful web experiences, inspiring improvements to the Codex website.
To add animation , the technical stack is as follows:
Technical Stack
| Technology | Purpose | Documentation |
|---|---|---|
| Next.js | React framework | https://nextjs.org/docs |
| React 19 | UI library | https://react.dev/ |
| Tailwind CSS v4 | Styling | https://tailwindcss.com/ |
| JavaScript | Programming language | https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide |
| GSAP | Animation library | https://gsap.com/docs/v3/ |
With that in head , let us dive into the implementation process.
Implementation Process
Step 1: Research and Discovery
CodePen Resources and YouTube Tutorials
- Explored animations from the following sources:
- GSAP Search Results: CodePen GSAP Search
- GreenSock Official Page: CodePen GreenSock
- CodeGrid Channel: YouTube
Step 2: Animation Review
Most animations on CodePen are pre-built using native web technologies:
- HTML
- CSS
- JavaScript
All available animations were reviewed to identify those that would work harmoniously on the homepage.
Step 3: Local Testing
Create Feature Branch
git switch -c feat/animations
Trial and Error Phase
- Test animations locally on the website
- Experiment with different combinations
- Evaluate which animations create a harmonious homepage experience
- Iterate until the desired aesthetic is achieved
Step 4: Installation
Install the GSAP React package:
npm install @gsap/react
Step 5: Conversion to React
After testing and selecting specific animations, the conversion process began using the @gsap/react framework. This allows seamless conversion of native HTML/CSS/JavaScript animations into:
- React components
- Tailwind CSS styling
This is the core animation template .
Core Animation Template
Basic Component Structure
// MyAnimation.tsx // Import React and the useRef hook // useRef lets us reference a real DOM element import React, { useRef } from "react"; // Import GSAP core library (animation engine) import gsap from "gsap"; // Import the official React hook from GSAP // This integrates GSAP cleanly into React lifecycle import { useGSAP } from "@gsap/react"; // Import CSS file for styling (layout, positioning, colors, etc.) import "./my-animation.css"; // Register the React plugin with GSAP // Required before using useGSAP gsap.registerPlugin(useGSAP); const MyAnimation: React.FC = () => { // Create a ref that will point to the root div // TypeScript knows it will reference a HTMLDivElement const scope = useRef<HTMLDivElement | null>(null); // useGSAP runs animation code after the component mounts // It also handles cleanup automatically useGSAP( () => { // ============================== // Your GSAP animation code goes here // ============================== // Example animation: // Animate elements with class ".box" // This selector will be scoped inside "scope" gsap.from(".box", { y: 100, // start 100px lower opacity: 0, // start invisible duration: 1, // animation lasts 1 second ease: "power3.out" }); // Important: // Because we passed { scope } below, // ".box" only targets elements inside this component, // not globally in the entire app. }, { scope, // This scopes all GSAP selector queries to this component only } ); return ( // Attach the ref to this root div // Now scope.current points to this DOM element <div ref={scope} className="animation-root"> {/* Example animated element */} {/* This element will be animated by gsap.from above */} <div className="box"> Animated Box </div> </div> ); }; export default MyAnimation;
Key React Concepts for Animations
Understanding useRef Hook
According to the React documentation, useRef is a React hook that lets you store a value that:
- Persists between renders - the value doesn't reset on each render
- Does NOT trigger re-renders when it changes
- Can reference a real DOM element - essential for GSAP animations
Understanding useLayoutEffect Hook
useLayoutEffect is a React hook that runs after React has updated the DOM but before the browser paints the screen. This timing difference is critical for animation and layout-related logic.
The React Rendering Sequence
When a React component renders, this sequence occurs:
- React calculates what should change
- React updates the real DOM
- The browser paints those changes to the screen
useLayoutEffect runs between steps 2 and 3. It executes after the DOM is ready but before the user visually sees anything.
Why This Matters for Animations
Animations and layout measurements depend on the DOM being fully updated. When you:
- Access containerRef.current and trackRef.current
- Read values like track.scrollWidth and window.innerWidth
These values are only reliable after the DOM has been updated. Reading them too early would return incorrect or null values.
useLayoutEffect guarantees that:
- DOM nodes exist
- Layout information is accurate
- You can safely calculate distances and register ScrollTrigger
useLayoutEffect vs useEffect
useEffect runs after the browser has already painted the screen. If you used useEffect for layout calculations and initial GSAP setup:
- The browser would first paint the unanimated layout
- Only afterward would your animation apply transforms like x or y
- This causes a visible flicker or jump - elements briefly appear in their default position before being animated
useLayoutEffect prevents this by allowing you to set the correct transform before the first paint, making the animation smooth and intentional.
Cleanup and Consistency
When you create GSAP animations and ScrollTriggers inside useLayoutEffect, you return a cleanup function that calls ctx.revert(). React guarantees this cleanup runs:
- Before the component unmounts
- Before the effect re-runs
Because this happens in the layout phase, you avoid:
- Leftover transforms
- Pinned states
- Duplicated ScrollTriggers when navigating between pages
Summary
The importance of useLayoutEffect for GSAP animations connects to three critical aspects:
- Accurate layout measurement - DOM dimensions and positions are correctly calculated
- Prevention of visual flicker - animations apply before the first paint
- Correct synchronization - DOM updates and animation setup are properly timed
When your animation logic depends on the physical size, position, or scroll behavior of elements, useLayoutEffect is the correct tool because it runs at the precise moment when the DOM is ready but not yet painted.
Thanks for reading !
Alain Ngongang