vue-virtual-scroller
Render large Vue 3 lists smoothly by virtualizing the DOM and recycling views, without giving up control over your markup.
Repository Health
Technical Analysis
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
Directus
CMS · Low Code Platforms
Connect any SQL database and get instant REST and GraphQL APIs, a visual management Studio, and a native MCP server for AI agents — free for most organizations.
GitLab
Devops · Developer Tools
The complete DevOps platform that unifies Git hosting, CI/CD, issue tracking, and security scanning into a single self-hostable application.
Kestra
Devops · Data Engineering · Automation
Event-driven orchestration platform for data, AI, and infrastructure workflows — define everything in YAML, run anywhere at scale.
massCode
Developer Tools · Productivity · Code Editors
A free, local-first developer workspace unifying snippets, notes, HTTP requests, calculations, drawings, and dev tools in one desktop app.
n8n
Automation · No Code Platforms
Code when you need it, UI when you don't — the workflow automation platform built for technical teams who refuse to choose.