October 14, 2026
Some sites scroll like they are on rails. You flick the wheel and the page glides to a stop instead of jumping. More often than not, that is Lenis, a small open-source library from darkroom.engineering that has become the default smooth scroller on award-winning sites. Here is how to confirm it in seconds, and how to reproduce the feel once you know.
The ten-second check
Open DevTools (F12), go to the Elements panel and look at the very first element,
<html>. While Lenis is running it adds classes there:
<html class="lenis lenis-smooth">
That is the whole test, and you can try it on this page: this blog uses Lenis.
Two related classes appear on demand. lenis-stopped appears when the
site pauses scrolling (behind a modal, for example), and lenis-scrolling
appears while it is moving.
For a fuller answer, paste this into the Console:
(() => {
const h = document.documentElement;
return {
classes: [...h.classList].filter(c => c.startsWith('lenis')),
preventAttrs: document.querySelectorAll('[data-lenis-prevent],[data-lenis-prevent-wheel],[data-lenis-prevent-touch]').length,
global: typeof window.Lenis === 'function' || !!window.lenis,
scriptHit: [...document.scripts].some(s => /lenis/i.test(s.src)),
};
})()
Classes on <html> are conclusive. data-lenis-prevent
attributes (which mark areas that should scroll natively, such as a code block or a
modal) are a strong sign. A global or a script URL containing lenis
confirms the library is loaded, though not always that it is switched on.
Feel the difference
Scroll inside both panes below. The left one is your browser’s native
scrolling. The right one uses the same core idea as Lenis: each frame, the position
moves a fraction of the way toward where you scrolled. Change lerp to
feel how much that one number controls.
The chart shows why it feels the way it does. The orange line jumps to each new
position. The green line chases it and never quite stops easing in. At
0.1, the smoothed position is still noticeably behind 300ms after you
stop. That lag is what reads as “weight”. Push lerp toward 0.03 and the
page starts to feel like it is underwater, a common mistake on over-designed
sites.
Lenis or a lookalike?
Several libraries produce smooth scrolling. They leave different fingerprints, and they behave differently when you try to rebuild them, so it is worth knowing which one you are looking at.
| Library | Fingerprint | How it works |
|---|---|---|
| Lenis | html.lenis, .lenis-smooth, data-lenis-prevent | Eases the real window scroll. Native scrollbar, position: sticky and anchors keep working. |
| GSAP ScrollSmoother | #smooth-wrapper and #smooth-content elements; GSAP globals | Moves a content wrapper with transforms, tightly integrated with ScrollTrigger. Part of GSAP. |
| Locomotive Scroll v4 | data-scroll-container, data-scroll, has-scroll-smooth class | Transforms a container. Common on sites built around 2019–2023. |
| Locomotive Scroll v5 | data-scroll attributes plus Lenis’s classes | Rebuilt on top of Lenis, so it passes the Lenis check as well. |
CSS scroll-behavior: smooth | The property on html; no library | Only smooths anchor jumps and scripted scrolls, not the mouse wheel. |
| Browser smooth scrolling | Nothing on the page | Your OS or browser setting animates wheel steps a little. It applies to every site, so it is not the site’s doing. |
Smooth scroll is almost never the whole story. It usually sits under an animation library that does the visible motion, typically GSAP with ScrollTrigger. To identify the rest of the stack, see how to find out what animation library a website uses.
The settings that create the feel
Lenis has two ways to define its motion, and sites use either:
lerp(linear interpolation, default0.1). Each frame, close that fraction of the remaining gap. It is frame-based and endlessly smooth, which is what the demo above uses.duration+easing. Each scroll takes a fixed time (for example1.2seconds) along an easing curve. This feels more designed and predictable. If a site sets a duration, it replaces lerp.
The other options that change the feel most:
| Option | What it changes |
|---|---|
wheelMultiplier | How far each wheel tick travels. Below 1 feels slow and heavy. |
touchMultiplier | The same for touch swipes, when touch smoothing is on. |
syncTouch | Whether touch devices are smoothed too. Off by default, because phones already have good momentum scrolling. |
orientation | vertical or horizontal scrolling for the whole page. |
infinite | Loops the page back to the top at the end. Rare, but distinctive when used. |
You cannot read these values from the page’s HTML. They live in JavaScript,
usually bundled and minified. A runtime capture
(reverse_engineer_animations in Enrichr) reports the Lenis instance’s
settings while the page is running, which saves hunting through a minified bundle
for lerp:.
Rebuilding it, with GSAP
Most Lenis sites pair it with GSAP ScrollTrigger. The two need one small bridge so ScrollTrigger hears about the smoothed position on every frame:
import Lenis from 'lenis';
import { gsap } from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';
gsap.registerPlugin(ScrollTrigger);
const lenis = new Lenis({ lerp: 0.1 }); // or { duration: 1.2 }
lenis.on('scroll', ScrollTrigger.update);
gsap.ticker.add((time) => lenis.raf(time * 1000));
gsap.ticker.lagSmoothing(0);
Without the last three lines, scroll-triggered animations stutter or lag behind the page, which is the most common complaint in Lenis rebuilds. If a section still feels wrong, the deeper walkthrough is in Three.js and GSAP: the two libraries behind almost every award-site hero.
Do it responsibly
Smooth scrolling changes how a basic browser behaviour works, so be careful with it:
- Respect reduced motion. If
prefers-reduced-motion: reducematches, skip Lenis or set lerp to 1. Long, floaty scrolling can cause real discomfort. - Exempt inner scrollers. Add
data-lenis-preventto modals, code blocks and anything with its own scrollbar, or they stop scrolling. The demo panes on this page use it, because this page runs Lenis too. - Test the keyboard. Space, Page Down and arrow keys should all still work, and in-page anchor links should land on the right place.
FAQ
How do I know if a website uses Lenis?
Inspect the html element. If its classes include lenis and lenis-smooth, Lenis is running. You can also search the page’s scripts for “lenis” or look for data-lenis-prevent attributes on scrollable elements.
Does this site use Lenis?
Yes. This blog runs Lenis. Open DevTools on this page and you will see class="lenis lenis-smooth" on the html element.
What is the default lerp in Lenis?
0.1. Each frame, the scroll position moves 10% of the remaining distance to its target. Lower values feel heavier and floatier; higher values feel closer to native scrolling.
What is the difference between Lenis and GSAP ScrollSmoother?
ScrollSmoother wraps the page in #smooth-wrapper and #smooth-content and moves the content with transforms, integrated with ScrollTrigger. Lenis smooths the native scroll position directly and works with any animation library.
Is Lenis bad for accessibility?
It can be if used carelessly. Smooth scrolling can cause discomfort for people sensitive to motion. Respect prefers-reduced-motion by disabling smoothing for those users, and test keyboard scrolling and in-page anchors.