Nuxt Module for GSAP?

Nuxt 3 & GSAP: Why I Skip the Module and Go Manual

Main-Picture


In the Nuxt ecosystem, there is a module for almost everything. `@nuxtjs/gsap`? It exists. But just because a wrapper exists doesn’t mean you should always use it. 

If you’ve ever felt like a module was adding a layer of "magic" that made debugging harder rather than easier, this post is for you. Today, we’re going back to basics: installing GSAP via `npm` or `pnpm` and why it’s actually the superior way to handle animations in Nuxt 3.

---

## The "Module Fatigue" Realization

Nuxt modules are fantastic for complex integrations (like Supabase or Auth). But for a library like GSAP, which is essentially a collection of JavaScript utilities, a module often just provides:

1.  **Auto-imports:** Which take 2 seconds to set up manually.
2.  **Plugin registration:** Which can be handled in a single file.
3.  **Abstractions:** That might lag behind the actual GSAP version updates.

By sticking to `npm install gsap`, you keep your `package.json` lean, your bundle controlled, and your workflow closer to the official GSAP documentation.



---

## 1. The Setup

First, let’s get the library into your project. No fluff, just the core.

```bash
# Using pnpm (recommended)
pnpm add gsap

# Or npm
npm install gsap

2. Handling the SSR Trap

Nuxt is a Server-Side Rendering (SSR) framework. GSAP, however, lives for the DOM. If GSAP tries to run on the server, your build will scream.

The “Manual” way forces you to be conscious of the lifecycle, which is actually a good thing. We use onMounted or import.meta.client checks to ensure GSAP only wakes up when there’s a browser window to play with.

The Component Level Approach

Code-Snippet

<script setup>
import { gsap } from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';

// Register plugins only on the client
if (import.meta.client) {
  gsap.registerPlugin(ScrollTrigger);
}

const main = ref(null);

onMounted(() => {
  // Use a context for easy cleanup!
  let ctx = gsap.context(() => {
    gsap.to(".box", { 
      rotation: 360, 
      duration: 2, 
      scrollTrigger: ".box" 
    });
  }, main.value); // Scoped to this component
});

onUnmounted(() => {
  // Clean up to prevent memory leaks
  ctx.revert();
});
</script>

<template>
  <div ref="main">
    <div class="box w-20 h-20 bg-green-500"></div>
  </div>
</template>


3. Pro Tip: The useGsap Composable

If you want the “cleanliness” of a module without the overhead, create a custom composable. This gives you auto-imports and a consistent pattern across your app.

Create composables/useGsap.js:

JavaScript

import { gsap } from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';

export const useGsap = () => {
  if (import.meta.client) {
    gsap.registerPlugin(ScrollTrigger);
  }
  
  return {
    gsap,
    ScrollTrigger
  };
};

Now, in any component, you just call const { gsap } = useGsap() and you’re off to the races.


Conclusion: Control is Key

Modules are great, but understanding the underlying tools is better. By installing GSAP manually, you:

  • Reduce Technical Debt: You aren’t dependent on a third-party maintainer to update the wrapper.

  • Better Debugging: Error messages come straight from GSAP, not a Nuxt-specific abstraction.

  • Smaller Footprint: You only import exactly what you use.

Sometimes, the best way to “Nuxt” is to just use “JavaScript.”

What’s your take? Do you prefer the “install and forget” nature of modules, or do you like getting your hands dirty with the core library? Let me know in the comments!

Comments

Popular posts from this blog

My first Blog