FINDING YOUR DIRECTION

0%
← Scrollhaus Journal

AI Website Guides · 2026-10-05 · 5 min read

Lenis Smooth Scroll Tutorial: Setup, GSAP & React (2026)

Lenis is a lightweight smooth scroll library that turns jumpy mouse-wheel scrolling into eased, fluid motion without hijacking the native scrollbar. This tutorial covers setup, GSAP ScrollTrigger sync, React usage and the bugs that trip people up.

Written by AmJ, founder of Scrollhaus, and edited by the Scrollhaus editorial team. Sources and methodology are documented in the article.

A scroll-driven animated website with smooth eased scrolling
Scrollhaus Journal · AI Website Guides

Key takeaways

    Disclosure: ScrollHaus publishes this guide. Technique descriptions come from public documentation of the libraries and browser APIs named, and the live examples are ScrollHaus websites you can scroll yourself.

    What is Lenis smooth scroll?

    Lenis is a small open-source library that smooths scrolling. Browsers move the page in discrete steps when a mouse wheel turns. Lenis intercepts wheel and touch input, eases the movement toward the target position, and applies the result to the real scroll position. Because it uses the native scroll position, position: sticky, anchor links, accessibility tools and scroll-driven libraries keep working. That is the main reason designers choose it over older "scroll jacking" approaches.

    Install and start Lenis

    npm install lenis
    
    import Lenis from 'lenis';
    
    const lenis = new Lenis({
      duration: 1.2,
      easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)),
      smoothWheel: true,
    });
    
    function raf(time) {
      lenis.raf(time);
      requestAnimationFrame(raf);
    }
    requestAnimationFrame(raf);

    Add the recommended CSS from the Lenis documentation so native smooth scrolling does not fight the library: html.lenis, html.lenis body { height: auto; } and .lenis.lenis-smooth { scroll-behavior: auto !important; }.

    Sync Lenis with GSAP ScrollTrigger

    If you use GSAP ScrollTrigger, tell it when Lenis scrolls and let GSAP's ticker drive Lenis so both share one clock:

    import gsap from 'gsap';
    import { ScrollTrigger } from 'gsap/ScrollTrigger';
    gsap.registerPlugin(ScrollTrigger);
    
    lenis.on('scroll', ScrollTrigger.update);
    gsap.ticker.add((time) => lenis.raf(time * 1000));
    gsap.ticker.lagSmoothing(0);

    Without the ticker line you run two animation loops and see jitter. See our GSAP ScrollTrigger examples for what to build on top.

    Lenis in React and Next.js

    Create the instance in an effect, drive it with requestAnimationFrame, and destroy it on cleanup so hot reloads and route changes do not stack instances:

    useEffect(() => {
      const lenis = new Lenis();
      let id;
      const raf = (t) => { lenis.raf(t); id = requestAnimationFrame(raf); };
      id = requestAnimationFrame(raf);
      return () => { cancelAnimationFrame(id); lenis.destroy(); };
    }, []);

    Anchor links, modals and nested scrolling

    Does Lenis work on mobile?

    Touch scrolling on phones is already smooth and inertial, so Lenis leaves it native by default. That is a feature: you keep platform feel and avoid the battery cost of a custom loop. Tune syncTouch only if you need identical behavior across devices.

    Common Lenis problems and fixes

    Lenis plus a frame-sequence canvas

    Smooth scrolling is what makes a scroll-driven film feel premium. Pair it with the image sequence canvas technique and open a live example such as CORNERSTONE or VORTA to see the result. More background: scroll animation websites and scroll animation performance.

    Explore animated website templates at Scrollhaus →

    Need help with a template, account, or project? Email admin@scrollhaus.ai.