TanStack Virtual (React)
Headless React hook for virtualizing massive lists, grids, and tables at 60FPS.
Repository Health
Technical Analysis
@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
Promptfoo
AI Development
An open-source CLI and library for evaluating and red-teaming LLM applications — replace trial-and-error prompt engineering with systematic evals, vulnerability scanning, and CI/CD integration.
Rivet
AI Agents · Developer Tools
Stateful actors as a primitive for AI agents, real-time collaboration, and durable execution — with in-memory state, WebSockets, queues, and scheduling built in.
Rybbit
Analytics
Open-source, privacy-friendly web and product analytics with cookieless tracking, session replays, funnels, and real-time dashboards — a self-hostable alternative to Google Analytics.
Sanity
CMS
Open-source headless CMS with a fully customizable React Studio, real-time collaborative editing, structured content modeling, and GROQ query language
Sentry
Analytics · Developer Tools · Monitoring
Developer-first error tracking and performance monitoring platform with AI-powered root-cause analysis across 20+ languages and frameworks.
SigNoz
Analytics · Monitoring
Self-host your entire observability stack — logs, metrics, traces, and LLM monitoring — in one OpenTelemetry-native platform, without the Datadog bill.
Sourcebot
AI Code Assistants · Developer Tools · Search
A self-hosted, AI-powered code search engine that indexes every repo across GitHub, GitLab, Bitbucket, Gitea, Gerrit, and Azure DevOps, so both engineers and coding agents can search, browse, and ask questions about your codebase from one place.
Spacedrive
Collaboration · File Storage
One file manager for all your devices and clouds — powered by a Virtual Distributed File System built in Rust.
Hexclave
Authentication · Developer Tools
The open-source user infrastructure platform — authentication, teams, payments, emails, analytics, and more on a single unified user model.