Skip to main content
Journal

Engineering · Performance

Why we use Lenis (and when not to)

Smooth scroll is a budget item. After shipping a few sites with Lenis and a few without, here’s where we landed — and the test bug that bit us repeatedly.

GoSmartR5 min read

Smooth scroll is a polarising choice. Half of the developers we know swear by it; the other half open every site they encounter and try to disable it within five seconds. We’ve been on both sides. After shipping a few sites with Lenisand a few without, here’s where we landed.

When it helps

Lenis (or any momentum-scroll library) earns its weight when the page is built around scroll as a primary interaction. On this site, every long page has at least one scroll-driven theatre section: pinned animations that scrub through stages as you scroll. Without easing, those scrubs feel jittery whenever the visitor uses a trackpad with momentum baked in but not exposed to the JS scroll position.

Lenis decouples the visual scroll from the actual window.scrollY and animates between them. The result is that pinned + scrubbed sections — the home FinalTheater, the case study testimonial moments — feel deliberate instead of stuttery.

Smooth scroll is a budget item. Spend it where the page is actually choreographed. Skip it everywhere else.

— Working principle

When it hurts

We’ve hit three classes of problem with smooth scroll across client work:

1. Anchor links and back-to-top buttons

Native scroll respects URL fragments and history. Smooth scroll libraries usually don’t — you have to remember to call lenis.scrollTo() instead of window.scrollTo(). Forgetting once breaks every in-page anchor on the site, and the bug is invisible until a user reports it.

2. Programmatic scroll in tests

This is the one that bit us repeatedly. Headless browser tests that drive the page with programmatic window.scrollTo() will appear to scroll — the JS scroll position updates — but Lenis hasn’t advanced its internal animation, so the rendered transform is stuck at zero. Screenshots come back black. The test runner says everything passed.

3. Accessibility

Anyone with prefers-reduced-motion: reduce should never see momentum scroll. We wrap the Lenis provider so it falls back to native scroll when the OS-level setting is on. This is non-negotiable. Smooth scroll that steamrolls accessibility preferences is just hostile design with extra steps.

Our rule

On client sites with no choreographed scrolling — most marketing pages, blog posts, dashboards — we ship native scroll. It’s lighter, more accessible by default, and nobody ever complains. We add Lenis only when the design calls for pinned sections, scroll-driven storytelling, or elaborate parallax. Otherwise it’s a 6KB tax that breaks anchor links and confuses tests.

On this site, every long page has at least one pinned scrub, so Lenis stays. On /pricing, /journal, and the dashboard, the cost is paid because at the bottom of every page sits the FinalTheater — a three-act pinned scene that scrubs as you arrive. Without easing, that scrub would feel like a stop-motion film.

Related reading

Next in the journal

Notes on shipping FinalTheater

Most studio sites end the same way: a lime band, a CTA, an arrow. We replaced ours with a three-act pinned scene. Here’s what worked, what we tried that didn’t, and the small details that mattered.