A highly customizable, high-performance virtual scrollbar for rendering large data sets. Ships framework-specific adapters for React and Vue 3, built on a shared framework-agnostic core.
| Package | Description | Version |
|---|---|---|
@better-scrollbar/core |
Framework-neutral algorithms and utilities | |
@better-scrollbar/react |
React adapter (component, hooks, render props) | |
@better-scrollbar/vue |
Vue 3 adapter (component, composables) | |
better-scrollbar |
Compatibility wrapper — re-exports @better-scrollbar/react |
Migrating from v1? The
better-scrollbarpackage continues to export the same React API. No changes are required unless you want to switch to the scoped@better-scrollbar/reactimport.
- Children mode for regular lists with familiar JSX / slot syntax.
- Indexed rendering with
itemCount+renderItem/ scoped slot for massive data sets (millions of rows). - Dynamic height measurement via a shared
ResizeObserverwith LRU cache. - Custom scrollbar tracks, thumbs, and view wrappers through render props (React) or slots (Vue).
- Scroll anchoring that preserves visible position during prepend and resize.
- Bottom-following output for log and chat-style views.
- Sticky rows and group headers with
stickyIndices/groupCounts. - Native scroll mode that delegates to the browser when possible.
- Scroll seek placeholders during fast scrolling for expensive row renderers.
- Adaptive overscan that expands pre-rendering toward the scroll direction.
- Accessibility with built-in
role="list"/role="listitem"and ARIA position metadata.
pnpm add @better-scrollbar/react @better-scrollbar/coreimport ScrollBar from "@better-scrollbar/react"
import "@better-scrollbar/react/styles/ScrollBar.less"
export default function BasicList() {
return (
<ScrollBar width={500} height={300} itemHeight={32}>
<div key="a">Row A</div>
<div key="b">Row B</div>
<div key="c">Row C</div>
</ScrollBar>
)
}pnpm add @better-scrollbar/vue @better-scrollbar/core<script setup>
import { BScrollBar } from "@better-scrollbar/vue"
import "@better-scrollbar/vue/styles/ScrollBar.less"
</script>
<template>
<BScrollBar :item-count="10000" :estimated-item-height="32" :height="400">
<template #default="{ index }">
<div>Row {{ index }}</div>
</template>
</BScrollBar>
</template>- React API Reference — full props, types, and ref API.
- Vue API Reference — props, events, exposed methods, and composables.
- Core API Reference — algorithms, virtual height index, and shared types.
- Detailed API Reference — comprehensive props table with defaults.
- Optimization Practices — design decisions and industry references.
- Contributing — development setup and pull request guidelines.
- Security Policy — vulnerability reporting.
- Changelog — release history.
better-scrollbar/
├── packages/
│ ├── core/ # @better-scrollbar/core — algorithms, types, utilities
│ ├── react/ # @better-scrollbar/react — React component & hooks
│ └── vue/ # @better-scrollbar/vue — Vue 3 component & composables
├── apps/
│ └── site/ # Documentation site (React)
├── build/ # Compatibility package entry (re-exports @better-scrollbar/react)
└── docs/ # Design docs and detailed API reference
This repository uses pnpm workspaces and Turborepo for task orchestration.
corepack enable
pnpm install --frozen-lockfile| Command | Description |
|---|---|
pnpm run build |
Build all packages via Turborepo |
pnpm run dev |
Start dev mode for all packages |
pnpm run typecheck |
Type-check all packages |
pnpm run lint |
Lint all source files with ESLint |
pnpm run test |
Run tests with coverage |
pnpm run clean |
Remove all build artifacts |
pnpm run site:dev |
Start the documentation site dev server |
pnpm run site:build |
Build the documentation site |
Any browser that supports ResizeObserver (Chrome 64+, Firefox 69+, Safari 13.1+, Edge 79+). A polyfill is included as a fallback for older environments.