Lenis Smooth Scrolling: Elevate Your Web Animations with Buttery Smoothness
In the pursuit of creating immersive and polished web experiences, every detail matters. One of the most noticeable differentiators between a good website and a great one is the quality of its scroll interactions. Native browser scrolling, while functional, can often feel janky, abrupt, and disconnected from the rest of a site's fluid animations. This is where Lenis comes in—a modern, lightweight, and performance-focused smooth scroll library that brings a new level of elegance and control to user navigation.
Lenis is not just about making scrolling "slow." It's about making it smooth, responsive, and consistent across all devices and browsers. It solves the common pitfalls of smooth scrolling, such as lag on low-end devices, broken accessibility, and interference with native scroll-based features. By delegating scroll rendering to a requestAnimationFrame loop, Lenis ensures that your scrolling is perfectly in sync with your other animations, creating a seamless, app-like feel that users love.
Why Choose Lenis Over Native Scrolling or Other Libraries?
You might wonder why you need a library for something the browser does natively. The answer lies in control, performance, and consistency.
Eliminates Jank and Stutter: Native scrolling can sometimes feel choppy, especially during complex parallax or animation sequences. Lenis provides a consistently smooth 60 FPS experience.
Unparalleled Control: It gives you fine-grained control over the scroll behavior, including damping (inertia), easing, and duration, allowing you to tailor the feel to your brand's personality.
Respects User Preferences: A well-implemented Lenis setup respects the
prefers-reduced-motionmedia query, a critical aspect of web accessibility.Fixes Common Quirks: It automatically handles issues like smooth scrolling to anchor links and provides a robust foundation for scroll-triggered animations.
Lightweight and Modern: Unlike some older, more bloated jQuery plugins, Lenis is built with modern JavaScript and is tree-shakable, minimizing its impact on your bundle size.
How to Implement Lenis in Your Project
Getting started with Lenis is straightforward. Let's walk through the basic implementation.
Step 1: Installation
You can install Lenis via a package manager like npm or Yarn, or simply include it via a CDN.
Using npm:
bash
npm install lenisUsing a CDN (in your HTML):
html
<script src="https://unpkg.com/lenis@1.1.0/dist/lenis.min.js"></script>Step 2: Basic Initialization
Once the library is available, you need to initialize it in your JavaScript. The simplest setup is just a few lines of code.
javascript
// Import if using a module bundler (like Vite, Webpack)
import Lenis from 'lenis'
// Initialize Lenis
const lenis = new Lenis({
duration: 1.2, // Total duration of the scroll animation (in seconds)
easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)), // A custom easing function for a natural feel
direction: 'vertical', // 'vertical' or 'horizontal'
smooth: true, // Enable smooth scrolling
mouseMultiplier: 1, // How much the mouse wheel affects scrolling
})
// Start the animation loop
function raf(time) {
lenis.raf(time)
requestAnimationFrame(raf)
}
requestAnimationFrame(raf)Step 3: Essential CSS
To ensure Lenis works correctly, you need to set the height of your html and body elements. This is a crucial step that is often missed.
css
html {
height: 100%;
}
body {
min-height: 100%;
}Advanced Configuration and Usage
Lenis becomes truly powerful when you leverage its advanced features and integrate it with other tools.
Smooth Scrolling to Anchor Links
Lenis automatically makes anchor link scrolling smooth. Just use standard anchor links in your HTML.
html
<a href="#section-2">Go to Section 2</a>
...
<section id="section-2">...</section>Customizing Scroll Behavior
The constructor accepts an options object to fine-tune the scrolling experience.
javascript
const lenis = new Lenis({
duration: 1.5,
smoothWheel: true, // Smooth the mouse wheel scrolling
wheelMultiplier: 1.2, // Make the wheel a bit more sensitive
touchMultiplier: 1.5, // Make touch scrolling faster
});Listening to Scroll Events
You can listen to the scroll event emitted by Lenis to create custom scroll-driven logic. This is much smoother than using the native window.scroll event.
javascript
lenis.on('scroll', (e) => {
console.log(e.scroll, e.limit, e.velocity) // Log scroll position, total scrollable height, and scroll velocity
// Use this for custom progress indicators, etc.
})Powerful Integrations: Lenis with Animation Libraries
The real magic happens when you combine Lenis with a powerful animation library. This duo allows you to create complex, scroll-linked animations that are perfectly synchronized.
Integration with GSAP ScrollTrigger
GSAP's ScrollTrigger is the industry standard for scroll animations. Pairing it with Lenis is a match made in heaven.
javascript
import Lenis from 'lenis'
import gsap from 'gsap'
import ScrollTrigger from 'gsap/ScrollTrigger'
// Tell GSAP to use the ScrollTrigger plugin
gsap.registerPlugin(ScrollTrigger)
// Initialize Lenis
const lenis = new Lenis()
// Connect Lenis to ScrollTrigger
lenis.on('scroll', ScrollTrigger.update)
// Tell ScrollTrigger to use a proxy (Lenis) for scroll events
gsap.ticker.add((time) => {
lenis.raf(time * 1000) // Convert seconds to milliseconds
})
// Prevent GSAP's native lagSmoothing
gsap.ticker.lagSmoothing(0)
// Now create your ScrollTrigger animations as usual!
gsap.to(".box", {
scrollTrigger: {
trigger: ".box",
start: "top center",
end: "bottom top",
scrub: true,
},
x: 500,
rotation: 360,
});Integration with Framer Motion (React)
For React developers using Framer Motion, you can wrap your app in a Lenis context to enable smooth scrolling.
jsx
// components/LenisSmoothScroll.jsx
import React, { useEffect } from 'react';
import Lenis from 'lenis';
export const LenisSmoothScroll = ({ children }) => {
useEffect(() => {
const lenis = new Lenis();
function raf(time) {
lenis.raf(time);
requestAnimationFrame(raf);
}
requestAnimationFrame(raf);
// Cleanup on component unmount
return () => {
lenis.destroy();
};
}, []);
return <>{children}</>;
};
// Then, in your App.jsx
import { LenisSmoothScroll } from './components/LenisSmoothScroll';
import { MyComponent } from './MyComponent';
function App() {
return (
<LenisSmoothScroll>
<MyComponent />
</LenisSmoothScroll>
);
}Performance and Accessibility Best Practices
While Lenis is performant, it's crucial to use it responsibly.
Always Respect
prefers-reduced-motion: Some users are sensitive to animation. Disable Lenis for them.javascript
const lenis = new Lenis({ smooth: !window.matchMedia('(prefers-reduced-motion: reduce)').matches, });Test on Low-End Devices: Smooth scrolling can be more demanding on CPU. Ensure your site remains performant.
Don't Over-customize: Extreme damping or very long durations can make the site feel unresponsive. Subtlety is key.
Proper Cleanup: In Single Page Applications (SPAs), always call
lenis.destroy()when the component unmounts to prevent memory leaks.
Conclusion: A New Standard for Web Fluidity
Lenis represents a significant step forward in creating polished, professional web experiences. It solves a fundamental UX problem—clunky scrolling—with an elegant, performant, and developer-friendly solution. By integrating Lenis into your projects, you gain the tools to build websites that not only look beautiful but also feel incredibly responsive and refined. Whether you're building a simple portfolio or a complex, animation-heavy marketing site, Lenis provides the smooth foundation upon which you can build your best work.