Lerp

Lerp smooth scroll

Demo
Share of the remaining distance per 60 fps frame. 0.1 is Lenis's default.
What most product sites ship: the page moves with the wheel, 1:1.

Wheel scrolling that eases after the input, tuned by one number measured across the library.

How it works

Scroll· 68 sites

Reference: Lenis, darkroom.engineering

Measured in the library

Each value is fitted frame by frame to a site's 30 fps scroll capture, with the wheel input logged per frame. Range 0.057–0.494, median 0.1 over 32.

median 0.1 0.050.10.20.4

32 sites with a smoothed wheel, and 60 that scroll natively. Press a dot to scroll the demo like that site. Pro names the 49 hollow dots

On phones (touch, 18 sites): 0.177 to 1.005, including Paperclip 0.759. Touch is usually left unsmoothed.

How it works

Wheel scrolling that eases after the input, tuned by one number measured across the library.In 6 steps.

The smooth scroll on most expressive sites in the library is Lenis, and Lenis is one idea: the wheel moves a target, and every frame the page covers a fixed share of the distance left. That share, the lerp, is the whole feel. The library fits it frame by frame from each site's 30 fps scroll clip, so you can set it to a site you like instead of guessing.

  1. 01

    Take over the wheel

    Listen for wheel with passive: false, call preventDefault(), and add the delta to a target position clamped to the page's height. Convert line and page deltas to pixels.

  2. 02

    Ease towards the target every frame

    y += (target - y) * (1 - exp(-lerp * 60 * dt)). With dt in seconds this is the same curve at 60, 120 or 144 Hz; a plain y += (target - y) * lerp would run twice as fast on a 120 Hz screen.

  3. 03

    Move the page with a transform

    Translate the content wrapper (translate3d(0, -y px, 0)), or set scrollTop on the document if fixed and sticky elements must keep working (Lenis does the latter).

  4. 04

    Leave touch alone

    Phones already have momentum; a finger that lags feels broken. Follow touch 1:1 unless you have a reason (Lenis calls it syncTouch).

  5. 05

    Sleep at rest

    Stop the frame loop once the page is within a tenth of a pixel of the target, so a still page costs nothing.

  6. 06

    Read the number, not the curve

    The time constant 1000 / (lerp × 60) ms is how long the page takes to cover 63 % of a jump: 167 ms at 0.1, 290 ms at 0.057.

Code

The code

The engine is the file the demo above runs, framework-agnostic; the Svelte and React tabs wire it into a component.

Pro

Copy the engine, React or Svelte version.

Unlock code with Pro

US$60/year or US$8/month. Cancel anytime.

Prompt

Prompt pack

Wheel scrolling that eases after the input, tuned by one number measured across the library.

2 prompts in Pro Generated 25 Sep 2026

  • Build it with a coding agentSmooth scroll with a measured feel, as a brief for any coding agent.
  • Match a site's scrollFor when you want one site's exact weight.

Pro opens every prompt, with the measured values filled in and ready to paste into your coding agent.

Unlock prompts with Pro

US$60/year or US$8/month. Cancel anytime.

Performance & accessibility

Performance

The loop does one subtraction, one exp and one transform write per frame, and stops at rest. The cost is elsewhere: every scroll-linked effect now runs on the main thread in step with the eased position rather than the compositor's. Keep them to transforms and opacity, read layout once per frame, and avoid position: fixed inside a transformed wrapper (use the document-scrolling mode, as Lenis does, if you need sticky or fixed elements).

Reduced motion

Under prefers-reduced-motion, do not smooth at all: native scroll is the reduced-motion version (this demo switches to it). Keep keyboard scrolling, anchor links and the scrollbar working in every mode: they must move the target too, or skip the easing.

Source

Source, credited

Lenis (MIT, darkroom.engineering) is the library most of these sites load. The measured values come from this library's own captures: each site's scroll clip records the wheel input per frame, and npm run measure fits the page's position as a per-frame lerp. The demo engine is a small independent implementation of the same model.

Seen in the library

Sites using this effect.