
React GSAP Reveal
Context
GSAP is one of the most powerful animation libraries on the web. It can be used to create scroll-based reveal effects (making elements appear as they enter the viewport), but only in an imperative (manual) way.
In a React application codebase, this approach quickly becomes verbose, repetitive, and non-idiomatic, which discourages consistent use and harms UI consistency. Declarative reveal libraries do exist, but they don’t leverage the full power of GSAP. I wanted both: declarative simplicity and GSAP’s power under the hood.
From Personal Pattern to Public Library
It all started with a pattern implemented in a personal project:
- 👁️ A single IntersectionObserver, optimized through a subscription system to avoid creating one observer per element
- ✨ GSAP integration via an abstraction layer, encapsulated in a React component
The potential for reusability quickly became clear. I progressively refactored, generalized, and parameterized this pattern until it was robust and strongly typed enough to be reused across projects.
The next step was obvious: turning it into a published library.
Production and Release
- 🏗️ Extraction from the host project: setting up a Vite build and structuring the project as a standalone npm package
- ⚖️ Respect for intellectual property: GSAP declared as a peer dependency rather than a direct dependency, to comply with its license and let users manage their own version
- 🤖 CI/CD with GitHub Actions: automatic deployment of the demo site to GitHub Pages on every push
- 📦 npm publication: semantic versioning followed from day one
- 📖 Documentation: writing comprehensive documentation covering installation, configuration, and use cases
- 💬 Community feedback: post on the official GSAP forum to validate the architectural approach. Positive feedback from a long-time contributor (active since 2014)
- 📈 Adoption: peak of 899 weekly downloads around the time of release

Takeaways
This project taught me to think as a library author rather than a consumer.
In practice, the library significantly reduces the verbosity and development time required for scroll-based animations: a simple declarative component is all it takes.
It also reflects how I approach a recurring problem: identify a pattern, abstract it, and make it reusable. Here, I take it a step further by sharing it with the community.