Skip to main content

react-remove-scroll vs body-scroll-lock vs scroll-lock 2026

·PkgPulse Team
0

TL;DR

For modern React UI, choose react-remove-scroll. body-scroll-lock is mainly a legacy holdover, and scroll-lock is only the right choice when your requirements are genuinely simple.

Quick Comparison

Librarynpm packageWeekly downloadsLatestBest forBiggest tradeoff
react-remove-scrollreact-remove-scroll~54.9M/week2.7.2React modals, drawers, and command palettes that need reliable scroll locking without hand-rolled body management.It is more abstraction than you need for a one-off overlay.
body-scroll-lockbody-scroll-lock~1.5M/week4.0.0-beta.0Legacy codebases that already use it or plain DOM apps that need allowTouchMove behavior for nested scrollers.Maintenance status and edge-case handling are weaker than you want for greenfield work.
scroll-lockscroll-lock~40K/week2.1.5Simple desktop-first overlays in plain JavaScript apps where a minimal dependency is more important than rich edge-case handling.The simplest option here is also the easiest one to outgrow.

Why this comparison matters in 2026

Scroll locking sounds easy until iOS Safari, nested drawers, or fixed headers enter the picture. This comparison is less about API syntax and more about whether the library can survive real modal and overlay behavior in production.

In 2026, command palettes, drawers, and layered overlays are standard UI. Users expect scroll to stay stable, scrollbar width to avoid layout shift, and touch devices to behave correctly. Bad scroll locking still makes polished apps feel broken faster than most visual bugs.

This topic is intentionally adjacent to existing PkgPulse coverage, not a duplicate. Existing PkgPulse coverage goes deep on popovers and component primitives. This article narrows the scope to scroll locking, which is where modal bugs usually hide.

What actually changes the decision

  • iOS Safari behavior is still the first thing to check. Desktop-only assumptions do not survive production mobile usage.
  • Nested scroll containers matter. The common case is not a single full-screen modal anymore; it is a drawer with its own internal scroll region.
  • Framework fit matters because body-level overflow mutations can easily fight with focus-lock, portals, or component library internals.

react-remove-scroll

Package: react-remove-scroll | Weekly downloads: ~54.9M | Latest: 2.7.2

react-remove-scroll is the safe default for serious React products because it understands the broader overlay stack instead of only toggling overflow: hidden on the body.

import { RemoveScroll } from 'react-remove-scroll';

{open && (
  <RemoveScroll>
    <DialogContent />
  </RemoveScroll>
)}

Best for: React modals, drawers, and command palettes that need reliable scroll locking without hand-rolled body management. Tradeoff: It is more abstraction than you need for a one-off overlay.

Strengths:

  • Handles common React portal patterns well
  • Good behavior around scrollbar compensation
  • Plays nicely with accessible overlay stacks

Watch-outs:

  • React-only
  • Larger than a minimal vanilla helper

body-scroll-lock

Package: body-scroll-lock | Weekly downloads: ~1.5M | Latest: 4.0.0-beta.0

body-scroll-lock is still common because teams shipped it years ago. For new work, it is harder to recommend as the default when safer abstractions exist.

import { disableBodyScroll, enableBodyScroll } from 'body-scroll-lock';

const panel = document.getElementById('drawer');
disableBodyScroll(panel, { allowTouchMove: (el) => el.closest('[data-scrollable]') !== null });

Best for: Legacy codebases that already use it or plain DOM apps that need allowTouchMove behavior for nested scrollers. Tradeoff: Maintenance status and edge-case handling are weaker than you want for greenfield work.

Strengths:

  • Familiar API
  • Useful nested-scroll exceptions
  • Works outside React

Watch-outs:

  • Maintenance has slowed
  • Still requires careful cleanup discipline

scroll-lock

Package: scroll-lock | Weekly downloads: ~40K | Latest: 2.1.5

scroll-lock is enough when your product genuinely has one or two simple overlays. It becomes a liability when overlay behavior grows more complex.

import scrollLock from 'scroll-lock';

scrollLock.disablePageScroll();
// ...open overlay...
scrollLock.enablePageScroll();

Best for: Simple desktop-first overlays in plain JavaScript apps where a minimal dependency is more important than rich edge-case handling. Tradeoff: The simplest option here is also the easiest one to outgrow.

Strengths:

  • Small and straightforward
  • Vanilla JS friendly
  • Fast to wire up for a single overlay

Watch-outs:

  • Thin mobile story
  • Less robust around nested scrollers and advanced overlay stacks

Which one should you choose?

  • Choose react-remove-scroll when react modals, drawers, and command palettes that need reliable scroll locking without hand-rolled body management.
  • Choose body-scroll-lock when legacy codebases that already use it or plain DOM apps that need allowTouchMove behavior for nested scrollers.
  • Choose scroll-lock when simple desktop-first overlays in plain JavaScript apps where a minimal dependency is more important than rich edge-case handling.

Final recommendation

For modern React UI, choose react-remove-scroll. body-scroll-lock is mainly a legacy holdover, and scroll-lock is only the right choice when your requirements are genuinely simple.

Floating UI vs Tippy.js vs Radix Tooltip/Popover 2026 · React Aria vs Radix Primitives 2026

The 2026 JavaScript Stack Cheatsheet

One PDF: the best package for every category (ORMs, bundlers, auth, testing, state management). Used by 500+ devs. Free, updated monthly.