TanStack Virtual (React)

Headless React hook for virtualizing massive lists, grids, and tables at 60FPS.

Library
npm
v3.14.22
7,158 stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
91 /100 Excellent
Development Activity 100
Maintenance 100
Community 64
Maturity 60
Momentum 40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
85 /100 Excellent
Architecture 88
Code Quality 90
Innovation 85
Learning Curve 78

@tanstack/react-virtual is the React binding for TanStack Virtual, a headless virtualization engine that renders only the rows or cells currently visible in a scroll container instead of the entire dataset. It ships as a pair of hooks — useVirtualizer for scoped scroll containers and useWindowVirtualizer for window-level scrolling — that compute item positions, expose a getVirtualItems() list to map over, and hand back scroll-to helpers, while leaving all markup and styling entirely to the consumer.

Because it wraps @tanstack/virtual-core, the same imperative engine that also powers the Vue, Solid, Svelte, Angular, Lit, and Marko bindings in the TanStack/virtual monorepo, the React package inherits dynamic/measured item sizing, horizontal and vertical layouts, multi-lane grid and masonry support, sticky items, and an optional direct-DOM-write mode that bypasses React re-renders for scroll-only updates. It has no required dependencies beyond virtual-core itself and peer-depends only on react and react-dom.

What You Get

  • useVirtualizer hook for virtualizing any scrollable container (vertical, horizontal, or grid layouts)
  • useWindowVirtualizer hook for virtualizing against the browser window’s own scroll position
  • Dynamic item measurement via measureElement, so row heights don’t need to be known up front
  • An optional directDomUpdates mode that writes item positions and container size straight to the DOM, skipping React re-renders on scroll-only updates
  • Full re-export of @tanstack/virtual-core primitives (scrollToIndex, scrollToOffset, getTotalSize, isScrolling, lanes for grid/masonry layouts)
  • Zero required styling — you own every pixel of markup and CSS, the hook only supplies positions and sizes

Common Use Cases

  • Rendering large data tables or spreadsheets where only a few dozen rows are visible at once
  • Infinite-scroll feeds (chat logs, activity streams, search results) that keep growing without a hard page limit
  • Virtualized dropdown/combobox option lists with thousands of selectable items
  • Masonry or multi-column grids (image galleries, card layouts) that need per-lane virtualization
  • Chat UIs that need to stay pinned to the bottom while new messages stream in

Under The Hood

Architecture

The React package is a thin adapter (single ~260-line packages/react-virtual/src/index.tsx) over the framework-agnostic Virtualizer class in packages/virtual-core/src/index.ts (~2,000 lines). useVirtualizerBase constructs one Virtualizer instance via React.useState, feeds it resolvedOptions on every render via instance.setOptions, and wires _didMount/_willUpdate into useIsomorphicLayoutEffect so the imperative core’s ResizeObserver-based measurement (observeElementRect/observeElementOffset) stays synced with React’s commit phase. Re-renders are triggered from the core’s onChange callback via a useReducer counter, either batched through flushSync (useFlushSync, default true, so scroll updates paint in the same frame) or deferred; when directDomUpdates is enabled, an internal directRef WeakMap-keyed cache lets applyDirectStyles write transform/top-left and container size straight to matched DOM nodes (looked up in the core’s elementsCache) and skip a re-render entirely unless the visible index range or isScrolling actually changes. The same core also backs the Vue, Solid, Svelte, Angular, Lit, and Marko packages in this monorepo, so all virtualization logic (range calculation, dynamic sizing, lanes for grid/masonry, scrollToIndex/scrollToOffset) lives in one place and each binding only implements framework-specific mounting and reactivity glue.

Tech Stack

Written entirely in strict TypeScript (target ES2020, noUncheckedIndexedAccess enabled) with zero required runtime dependencies beyond the workspace’s own @tanstack/virtual-core; react and react-dom are peer dependencies supporting ^16.8.0 through ^19.x. The monorepo is orchestrated with Nx (nx.json, pnpm workspaces, pnpm@11.9.0) and each package builds with Vite (vite.config.ts) into dual ESM/CJS output (dist/esm, dist/cjs) plus generated .d.ts files, validated with publint —strict for package.json export correctness. Dev/test tooling is Vitest for unit tests, Playwright for e2e (packages/react-virtual/tests/e2e), ESLint + a shared TanStack config, Prettier, sherif (workspace lint), and knip (unused-export detection) — all wired through nx affected so CI only reruns targets touched by a change.

Code Quality

packages/react-virtual/tests/index.test.tsx exercises the hook through @testing-library/react against a real List component with configurable count/overscan/height/gap/dynamic-sizing props, and mocks scrollHeight/scrollWidth on HTMLElement.prototype since jsdom doesn’t implement layout — a deliberate, well-documented workaround rather than a skipped test. A dedicated e2e suite runs under Playwright against the examples directory for real-browser scroll behavior, which unit tests alone can’t validate. Source code is thoroughly commented at decision points (e.g. the isIOSWebKit momentum-scroll workaround, the WeakMap-keyed direct-DOM-write cache) explaining why rather than what. Naming is consistent and descriptive (resizeItem, calculateRange, applyDirectStyles) and the public API is fully typed generically over TScrollElement/TItemElement, giving strong compile-time guarantees without any any escapes in the reviewed entry points.

API Design The public surface is deliberately small: two hooks (useVirtualizer, useWindowVirtualizer) that return a single object exposing getVirtualItems(), getTotalSize(), scrollToIndex/scrollToOffset, and a measureElement ref callback — everything else (markup, styling, keys) is left to the caller, which keeps the API framework-idiomatic and avoids prop sprawl. Sensible defaults (useFlushSync=true, directDomUpdates=false) mean a minimal working list needs only getScrollElement, count, and estimateSize, while advanced knobs (directDomUpdatesMode, rangeExtractor, lanes, gap) are opt-in and documented inline via TSDoc comments that explain the tradeoffs (e.g. ‘transform’ vs ‘position’ mode for directDomUpdates) directly at the point of use. The full virtual-core API is re-exported from the React entrypoint, so consumers never need a second import from @tanstack/virtual-core, and the official docs site (tanstack.com/virtual) plus the examples/react directory (12 worked examples: fixed, dynamic, grid, masonry, chat, infinite-scroll, sticky, window, table) keep the learning curve low despite the engine’s internal complexity.

Used by 83 apps in this directory

TypeScript
99%
Apache 2.0

Mastra Code

AI Code Assistants

29,041

"A coding agent that never compacts" — a terminal-based AI coding agent built on the Mastra framework, with Observational Memory instead of context compaction, multi-model support, and OAuth login for Claude Max or ChatGPT Plus.

View details
90
Repo Health
73
Technical
65
Dependency
Built with
TypeScript 99%
Updated 6 days ago
TypeScript
87%
MIT

medusa

Ecommerce

36,897

The most flexible open-source commerce platform — build B2C, B2B, and marketplace applications with modular, composable commerce primitives.

View details
94
Repo Health
87
Technical
63
Dependency
Built with
TypeScript 87%
JavaScript 12%
Updated 1 weeks ago
Rust
48%
MIT

Meetily

AI Assistants · Productivity

32,103

Privacy-first AI meeting assistant that transcribes and summarizes your meetings entirely on your local machine — no cloud, no data leakage.

View details
87
Repo Health
72
Technical
67
Dependency
Built with
Rust 48%
TypeScript 29%
Updated 1 weeks ago
Clojure
57%
Other

Metabase

Analytics

49,827

The open-source BI platform that lets anyone ask questions and build dashboards without writing SQL — with an embedded analytics SDK and AI-powered query assistant included.

View details
95
Repo Health
84
Technical
62
Dependency
Built with
Clojure 57%
TypeScript 38%
Updated 6 days ago
TypeScript
96%
AGPL 3.0

Midday

Invoicing Finance · Productivity

15,091

All-in-one AI-powered business operations platform for freelancers and solo entrepreneurs to manage invoicing, time tracking, banking, and financial intelligence.

View details
51
Repo Health
78
Technical
67
Dependency
Built with
TypeScript 96%
Updated 4 months ago
Python
58%
Apache 2.0

MLflow

AI Development · Monitoring

28,512

The open source AI engineering platform for debugging, evaluating, monitoring, and optimizing production LLMs and agents at scale.

View details
96
Repo Health
86
Technical
67
Dependency
Built with
Python 58%
TypeScript 35%
Updated 6 days ago
Go
56%
Other

Multica

AI Assistants · AI Development

53,682

Turn coding agents into real teammates — assign issues, track progress, and compound reusable skills across a vendor-neutral, self-hosted platform.

View details
87
Repo Health
83
Technical
67
Dependency
Built with
Go 56%
TypeScript 38%
Updated 6 days ago
TypeScript
97%
Other

nango

Authentication · Automation · Developer Tools

12,963

Build product integrations with AI using 800+ APIs — auth, proxy, and TypeScript functions on production-grade infrastructure.

View details
94
Repo Health
85
Technical
67
Dependency
Built with
TypeScript 97%
Updated 1 weeks ago
TypeScript
85%
GPL 3.0

Notesnook

File Storage · Note Taking · Security

14,822

End-to-end encrypted, open-source note-taking where your data stays yours — even from the server.

View details
91
Repo Health
84
Technical
60
Dependency
Built with
TypeScript 85%
JavaScript 12%
Updated 6 days ago

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