rc-scrollbars vs react-custom-scrollbars vs react-perfect-scrollbar vs react-scroll vs react-scrollbar-size
React Scrollbar and Scroll Management Libraries
rc-scrollbarsreact-custom-scrollbarsreact-perfect-scrollbarreact-scrollreact-scrollbar-sizeSimilar Packages:

React Scrollbar and Scroll Management Libraries

These libraries address different aspects of scroll behavior in React applications. rc-scrollbars, react-custom-scrollbars, and react-perfect-scrollbar provide customizable, cross-browser consistent scrollbar UIs that replace native scrollbars. react-scroll offers programmatic scrolling utilities for smooth navigation to elements or positions within the page. react-scrollbar-size is a utility package that detects the width of the browser's native scrollbar to help with layout calculations. While some focus on visual customization, others handle behavioral control or measurement.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
rc-scrollbars0158363 kB173 years agoMIT
react-custom-scrollbars03,224-2178 years agoMIT
react-perfect-scrollbar0481-606 years agoMIT
react-scroll04,419139 kB231a year agoMIT
react-scrollbar-size02816.9 kB15-MIT

React Scrollbar and Scroll Management: A Practical Comparison

When building polished React UIs, developers often encounter limitations with native scrollbars—especially their inconsistent appearance across browsers and operating systems. Other times, the need isn’t visual but behavioral: smoothly scrolling to sections, measuring scrollbar dimensions, or handling scroll events reliably. The packages rc-scrollbars, react-custom-scrollbars, react-perfect-scrollbar, react-scroll, and react-scrollbar-size each solve distinct problems in this space. Let’s break down what they do, how they differ, and where they fit in real-world apps.

🖼️ Custom Scrollbar Rendering: Replacing Native Scrollbars

Three of these packages aim to replace the browser’s default scrollbars with styled, consistent alternatives. However, their approaches and trade-offs vary significantly.

rc-scrollbars: Modern, Minimal, and React-Native

rc-scrollbars is built specifically for React using modern patterns. It avoids external dependencies and uses React’s own event system and refs for efficient updates. It supports auto-hide, thumb dragging, and works well with dynamic content.

import { Scrollbars } from 'rc-scrollbars';

function App() {
  return (
    <Scrollbars style={{ height: 300 }}>
      <div>Long content here...</div>
    </Scrollbars>
  );
}

It exposes render props for customizing track and thumb elements, enabling full design control:

<Scrollbars
  renderThumbVertical={({ style, ...props }) => (
    <div {...props} style={{ ...style, backgroundColor: '#888', borderRadius: '4px' }} />
  )}
/>

react-custom-scrollbars: Deprecated and Outdated

This package is officially deprecated (as noted on its npm page and GitHub repo). It hasn’t been updated in years and doesn’t support newer React versions well. It also has known issues with touch scrolling and accessibility.

// ❌ Avoid in new projects
import { Scrollbars } from 'react-custom-scrollbars';

<Scrollbars>
  <div>Content</div>
</Scrollbars>

While its API was flexible, the lack of maintenance makes it a liability. Use rc-scrollbars as a drop-in successor if migrating.

react-perfect-scrollbar: Wrapper Around a Non-React Library

react-perfect-scrollbar is a React wrapper for the standalone Perfect Scrollbar library. It provides highly customizable scrollbars that mimic native inertia and support advanced features like wheel propagation and RTL.

import PerfectScrollbar from 'react-perfect-scrollbar';
import 'react-perfect-scrollbar/dist/css/styles.css';

function App() {
  return (
    <PerfectScrollbar options={{ wheelPropagation: false }}>
      <div>Long content...</div>
    </PerfectScrollbar>
  );
}

However, because it relies on direct DOM manipulation and MutationObserver to detect content changes, it can be slower and less predictable in complex React trees. You must also manage CSS imports manually.

🧭 Programmatic Scrolling: Smooth Navigation Without Styling

Unlike the above, react-scroll doesn’t touch scrollbar appearance. Instead, it gives you tools to scroll smoothly to elements—ideal for single-page apps with anchor navigation.

import { Link, Element } from 'react-scroll';

function App() {
  return (
    <div>
      <Link to="section1" spy={true} smooth={true} offset={-50}>
        Go to Section 1
      </Link>
      
      <Element name="section1">
        <h2>Section 1</h2>
        <p>Content here...</p>
      </Element>
    </div>
  );
}

It also provides a scroller object for imperative control:

import { scroller } from 'react-scroll';

scroller.scrollTo('section2', {
  duration: 800,
  delay: 0,
  smooth: 'easeInOutQuart'
});

Use this when you need smooth in-page navigation but don’t care about scrollbar styling.

📏 Measuring Scrollbar Width: Layout Stability

react-scrollbar-size solves a subtle but critical layout problem: the scrollbar’s width varies by OS and browser (e.g., 17px on Windows Chrome, 0px on macOS with auto-hiding). This can cause unwanted layout shifts when content overflows.

The package provides a hook to read the current scrollbar width:

import { useScrollbarWidth } from 'react-scrollbar-size';

function App() {
  const scrollbarWidth = useScrollbarWidth();
  
  return (
    <div style={{ paddingRight: scrollbarWidth }}>
      Content that might trigger scrollbars
    </div>
  );
}

This is especially useful in modals, fixed headers, or grid layouts where precise alignment matters. Note: it doesn’t render anything—it’s purely a measurement utility.

⚖️ Key Trade-Offs Summarized

Concernrc-scrollbarsreact-custom-scrollbarsreact-perfect-scrollbarreact-scrollreact-scrollbar-size
Active Maintenance✅ Yes❌ Deprecated⚠️ Wrapper (depends on upstream)✅ Yes✅ Yes
Custom Scrollbar UI✅ Yes✅ Yes✅ Yes❌ No❌ No
Smooth Scrolling API❌ No❌ No❌ No✅ Yes❌ No
Scrollbar Measurement❌ No❌ No❌ No❌ No✅ Yes
Zero External CSS✅ Yes✅ Yes❌ Requires CSS import✅ Yes✅ Yes
Touch & Accessibility✅ Good❌ Poor⚠️ Mixed reportsN/AN/A

💡 When to Combine Packages

In practice, you might use more than one:

  • Use rc-scrollbars for custom scroll containers and react-scrollbar-size to adjust padding when native scrollbars appear elsewhere.
  • Use react-scroll for navigation alongside rc-scrollbars in a sidebar that needs custom styling.

But avoid combining multiple custom scrollbar libraries—they can conflict on the same DOM node.

🛑 Final Recommendations

  • For new projects needing custom scrollbars: Start with rc-scrollbars. It’s lightweight, React-native, and actively maintained.
  • Avoid react-custom-scrollbars entirely—it’s deprecated and unsafe for production.
  • Use react-perfect-scrollbar only if you need its specific visual fidelity and are willing to manage its external dependency and performance quirks.
  • Reach for react-scroll when implementing smooth anchor navigation, not for styling.
  • Add react-scrollbar-size only if layout shifts from scrollbar appearance are causing real UX issues—don’t over-engineer.

Each tool has its lane. Pick the one that matches your actual problem—not just the one with the most stars.

How to Choose: rc-scrollbars vs react-custom-scrollbars vs react-perfect-scrollbar vs react-scroll vs react-scrollbar-size

  • rc-scrollbars:

    Choose rc-scrollbars if you need a modern, lightweight, and actively maintained solution for custom scrollbars with good TypeScript support and minimal dependencies. It’s ideal for projects requiring clean, performant scrollbar replacement without heavy DOM manipulation or legacy baggage.

  • react-custom-scrollbars:

    Avoid react-custom-scrollbars in new projects — it is officially deprecated and no longer maintained. While it was once popular for its flexibility, it suffers from known issues with touch devices, dynamic content, and accessibility, and lacks updates for modern React features.

  • react-perfect-scrollbar:

    Choose react-perfect-scrollbar if you require pixel-perfect scrollbar styling that closely mimics native behavior while supporting features like wheel propagation and RTL. Be aware it wraps Perfect Scrollbar (a non-React library), which can lead to integration friction and potential performance overhead due to DOM mutation observers.

  • react-scroll:

    Choose react-scroll when your primary need is smooth, programmatic scrolling to elements or positions (e.g., single-page navigation, anchor links). It does not customize scrollbar appearance but excels at scroll behavior control with link components, events, and offset configuration.

  • react-scrollbar-size:

    Choose react-scrollbar-size only when you need to accurately measure the native scrollbar width for layout compensation (e.g., preventing layout shifts when scrollbars appear/disappear). It’s a niche utility, not a scrollbar replacement, and should be used alongside other layout or styling strategies.

README for rc-scrollbars

rc-scrollbars

rejuvenated project of react-custom-scrollbars

npm npm version npm downloads

  • frictionless native browser scrolling
  • native scrollbars for mobile devices
  • fully customizable
  • auto hide
  • auto height
  • universal (runs on client & server)
  • requestAnimationFrame for 60fps
  • no extra stylesheets
  • well tested, 100% code coverage

Documentation · Demos

Installation

npm install rc-scrollbars --save

# OR

yarn add rc-scrollbars

This assumes that you’re using npm package manager with a module bundler like Webpack or Browserify to consume CommonJS modules.

Usage

This is the minimal configuration. Check out the Documentation for advanced usage.

import { Scrollbars } from 'rc-scrollbars';

class App extends Component {
  render() {
    return (
      <Scrollbars style={{ width: 500, height: 300 }}>
        <p>Some great content...</p>
      </Scrollbars>
    );
  }
}

The <Scrollbars> component is completely customizable. Check out the following code:

import { Scrollbars } from 'rc-scrollbars';

class CustomScrollbars extends Component {
  render() {
    return (
      <Scrollbars
        onScroll={this.handleScroll}
        onScrollFrame={this.handleScrollFrame}
        onScrollStart={this.handleScrollStart}
        onScrollStop={this.handleScrollStop}
        onUpdate={this.handleUpdate}
        renderView={this.renderView}
        renderTrackHorizontal={this.renderTrackHorizontal}
        renderTrackVertical={this.renderTrackVertical}
        renderThumbHorizontal={this.renderThumbHorizontal}
        renderThumbVertical={this.renderThumbVertical}
        autoHide
        autoHideTimeout={1000}
        autoHideDuration={200}
        autoHeight
        autoHeightMin={0}
        autoHeightMax={200}
        thumbMinSize={30}
        universal={true}
        {...this.props} />
    );
  }
}

All properties are documented in the API docs

Run project locally

Run the simple example:

# Make sure that you've installed the dependencies
yarn
# Run tsc of Scrollbars in watch mode and the documentation project in dev env
yarn dev

License

MIT