vue-virtual-scroller

Render large Vue 3 lists smoothly by virtualizing the DOM and recycling views, without giving up control over your markup.

Library
npm
v3.0.5
10,794stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
62/100Good
Development Activity44
Maintenance40
Community64
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
85/100Excellent
Architecture88
Code Quality90
Innovation84
Learning Curve78

vue-virtual-scroller renders only the visible slice of a large list or grid in Vue 3, recycling DOM views as the user scrolls instead of mounting every item up front. It ships two ready-made components (RecycleScroller for fixed or already-known sizes, DynamicScroller for items that must be measured as they render), plus a WindowScroller wrapper for page-driven scrolling and a set of headless composables that expose the same virtualization engine to fully custom markup, including native tables.

The library ships ESM-only and targets Vue 3.3+ so component APIs can infer item types generically from the items prop. It supports grid layouts, prepend-anchored (shift) scrolling for chat-style feeds, cache snapshot/restore across remounts, server-side rendering via a prerender count, and a conditional enabled state for wrapping virtualization behind a parent toggle without remounting. Now in its v3 line with an active release cadence and a companion VitePress documentation site.

What You Get

  • RecycleScroller and DynamicScroller components plus a WindowScroller wrapper for page-driven scrolling
  • Headless composables (useRecycleScroller, useDynamicScroller, useWindowScroller, useTableColumnWidths) for fully custom markup
  • Full TypeScript generics that infer item types from the items prop on Vue 3.3+
  • Grid mode, variable-size mode, flow mode, and page mode to cover different layout needs
  • Cache snapshot/restore APIs to persist measured item sizes across remounts

Common Use Cases

  • Rendering chat or message feeds with unknown, variable item heights
  • Virtualizing large data tables and card/grid catalogs without mounting every row up front
  • Page-level infinite-scroll feeds driven by window or container scroll

Under The Hood

Architecture The package is organized into an engine layer (engine/scroll.ts, engine/cache.ts, engine/keyField.ts) holding pure, framework-agnostic virtualization math — offset/RTL normalization, cache-snapshot building and restoration, key resolution — fully decoupled from Vue reactivity. Composables (composables/useRecycleScroller.ts, useDynamicScroller.ts, useWindowScroller.ts, useTableColumnWidths.ts) wire that engine into Vue’s reactivity (ref/computed/watch/lifecycle hooks) and return a typed object (pool, visiblePool, totalSize, scrollToItem, etc.). Components (RecycleScroller.vue, DynamicScroller.vue, WindowScroller.vue, DynamicScrollerItem.vue) are thin wrappers that render the pooled views and forward scoped-slot props. Because DynamicScroller’s composable extends RecycleScroller’s rather than duplicating its logic, a change to core pooling or positioning behavior propagates to every component and headless consumer from one place.

Tech Stack Written in TypeScript targeting Vue 3.3+ as a peer dependency for generic component typing, built with Vite and vite-plugin-dts into ESM-only output with a granular per-entry exports map for each component and composable. The monorepo uses pnpm workspaces with a separate Vite + vue-router demo package for live examples and a VitePress-powered documentation site. Linting runs through the flat @antfu/eslint-config, release automation uses @akryum/sheep, and CI runs as GitHub Actions workflows for tests, continuous publishing, release notes, and PR title checks.

Code Quality Testing is extensive and colocated — nearly every composable, component, and engine module has a matching spec file (the RecycleScroller composable spec alone runs past 1,600 lines), executed through Vitest for unit tests and Playwright for browser-driven end-to-end coverage, plus a dedicated script that validates the published package’s export surface before release. Error handling favors explicit runtime warnings over silent failures, naming stays descriptive and consistent throughout the engine and composables, and the whole codebase is fully typed with exported generic interfaces so consumer type inference works without manual annotation. CI enforces lint, typecheck, unit, e2e, and package-export checks before every publish.

API Design The same virtualization engine is exposed through three layers — plug-and-play components, headless composables with full generic type inference, and pure engine functions — so a consumer can start with a component and drop to a composable only when custom markup like a table is needed, without switching libraries. Cache snapshot/restore is a deliberate answer to a common pain point in other virtualization libraries: keeping expensive DynamicScroller measurements alive across route changes or remounts. The enabled prop, which mounts a scroller in a fully passive state and re-arms it without remounting, solves a real composition problem — conditionally virtualizing a list behind a parent toggle — that’s usually solved elsewhere with a full v-if remount.

Used by 5 apps in this directory

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search