Design & Motion5 min read

Modern Web Motion: GSAP and Lenis Scroll

BY MANISH KUMAR
May 18, 2026

I wanted smooth scrolling on my site. Not the janky default where scroll happens in chunks. I wanted that buttery feel where things glide.

Turns out you need two things: a smooth scroll library and an animation library that plays nice with it.

The Setup

Lenis handles the smooth scroll. GSAP handles the animations. You wire them together like this:

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

gsap.registerPlugin(ScrollTrigger);

const lenis = new Lenis({
  duration: 1.2,
  easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)),
});

lenis.on('scroll', ScrollTrigger.update);

gsap.ticker.add((time) => {
  lenis.raf(time * 1000);
});

gsap.ticker.lagSmoothing(0);

Lenis intercepts the native scroll, applies easing, and feeds the position back to ScrollTrigger so animations stay in sync.

What Actually Matters for Performance

Three things I learned the hard way:

  1. Only animate transform and opacity. Don't touch margin, top, height — those trigger layout recalculations and kill your framerate.

  2. Group related scroll animations into one timeline instead of creating separate ScrollTrigger instances for each thing. Less listeners = smoother.

  3. Disable custom cursors and hover effects on touch devices. Use @media (pointer: coarse) in CSS. Touch devices don't need cursor tracking and it just wastes CPU.

That's really it. Smooth scroll isn't magic — it's just an event loop with easing on top.