react-custom-scrollbars-next
v1.0.1
Published
Drop-in replacement for react-custom-scrollbars-2, rebuilt with hooks and modern tooling
Downloads
224
Maintainers
Readme
react-custom-scrollbars-next
A modern, actively maintained, drop-in replacement for
react-custom-scrollbars-2.
✅ API compatible ✅ No migration required ✅ Same behavior, modern internals
Why this exists
react-custom-scrollbars-2 has not been updated in several years and relies on legacy tooling and abandoned dependencies.
This package preserves the exact public API and runtime behavior, while modernizing the internals for React 18+.
If you were using react-custom-scrollbars-2, no code changes are required.
What changed internally
The following internal changes were made WITHOUT affecting public behavior:
- Rewritten using React hooks and state management.
- Migrated to Typescript.
- Replaced legacy
rafdependency with nativerequestAnimationFrame. - Replaced legacy
dom-csswith a lightweight internal utility. - Removed Babel, Webpack, Karma.
- Built using modern ESM + CJS output.
Installation
npm install react-custom-scrollbars-nextUsage (unchanged example)
import Scrollbars from 'react-custom-scrollbars-next'API Compatibility and Parity Audit
react-custom-scrollbars-next is designed to be a **drop-in replacement for react-custom-scrollbars-2. The public API, runtime behavior, and DOM structure have been audited feature-by-feature to ensure full compatibility.
Public API
| Feature | Status |
|---------|--------|
| Default Export Scrollbars | ✅ Identical |
| Import style (`import Scrollbars from '...') | ✅ Identical |
| Component Props | ✅ Identical |
| Named Exports | ✅ None (Same as original) |
Props Compatibility
All public props from react-custom-scrollbars-2 are supported.
Layout & Behavior Props
| Prop | Status |
|----|----|
| style | ✅ |
| className | ✅ |
| autoHide | ✅ |
| autoHideTimeout | ✅ |
| autoHideDuration | ✅ |
| hideTracksWhenNotNeeded | ✅ |
| universal | ✅ (accepted, behavior matches original in modern SSR setups) |
Defaults and optionality match the original implementation.
Render Props
| Render Prop | Status |
|----|----|
| renderView | ✅ |
| renderTrackVertical | ✅ |
| renderTrackHorizontal | ✅ |
| renderThumbVertical | ✅ |
| renderThumbHorizontal | ✅ |
Render props:
- Receive the same arguments
- Are invoked at the same lifecycle moments
- Can fully control rendered DOM structure (same as original)
Scroll Callbacks
| Callback | Semantics | Status |
|----|----|----|
| onScroll | Native scroll passthrough | ✅ |
| onScrollStart | Fired once per scroll interaction | ✅ |
| onScrollFrame | RAF-batched | ✅ |
| onScrollStop | Fired after scroll inactivity | ✅ |
Callback ordering and timing match react-custom-scrollbars-2.
Imperative API (Refs)
All imperative methods exposed via ref are implemented with identical behavior.
| Method | Status |
|----|----|
| scrollTop(value?) | ✅ |
| scrollLeft(value?) | ✅ |
| scrollToTop() | ✅ |
| scrollToBottom() | ✅ |
| scrollToLeft() | ✅ |
| scrollToRight() | ✅ |
| getScrollTop() | ✅ |
| getScrollLeft() | ✅ |
| getScrollWidth() | ✅ |
| getScrollHeight() | ✅ |
| getClientWidth() | ✅ |
| getClientHeight() | ✅ |
Return values and side effects match the original component.
DOM Structure Compatibility
The rendered DOM structure is intentionally preserved to avoid breaking existing CSS overrides.
- Single root container
- Scrollable
viewelement - Vertical and horizontal tracks as siblings of the view
- Thumbs as children of their respective tracks
- No additional wrapper elements introduced
This ensures that custom styling targeting internal elements continues to work.
Interaction Parity
| Interaction | Status | |----|----| | Mouse wheel scrolling | ✅ | | Vertical thumb dragging | ✅ | | Horizontal thumb dragging | ✅ | | Track click paging | ✅ | | Auto-hide behavior | ✅ | | Hover behavior | ✅ | | Resize recalculation | ✅ |
Internal Modernization (Non-Breaking)
The following changes were made without affecting the public API or behavior:
- Rewritten using React hooks
- Migrated to TypeScript
- Removed dependency on legacy
raf - Removed dependency on legacy
dom-css - Replaced with native
requestAnimationFrameand lightweight internal utilities - Removed Babel, Webpack, and Karma
- Built using modern ESM + CJS outputs
These changes are strictly internal and do not require any consumer code changes.
Compatibility Statement
If you were using react-custom-scrollbars-2, you can replace it with
react-custom-scrollbars-next without modifying your code.
// before
import Scrollbars from 'react-custom-scrollbars-2';
// after
import Scrollbars from 'react-custom-scrollbars-next';