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 75 apps in this directory
Activepieces
Automation · AI Assistants
Open-source AI automation platform that converts 280+ workflow integrations into MCP servers for LLMs, with no-code builders and TypeScript extensibility.
agenta
Developer Tools · Devops · AI Development
The open-source LLMOps platform unifying prompt engineering, evaluation, and observability for teams building reliable LLM applications.
Agents Observe
Developer Tools
A real-time, fully local observability dashboard for Claude Code and Codex agent sessions — filtering, search, session replay, and token/cost breakdowns via an auto-starting MCP server.
Apache Airflow
Data Engineering
Define, schedule, and monitor complex data workflows as Python code — with a powerful UI, 80+ provider integrations, and battle-tested scalability across thousands of production deployments.
Bramble
Password Manager · Security · Authentication
Local-first, end-to-end encrypted password manager that syncs your vault directly between your own devices over a private peer-to-peer mesh — no server, no account, no cloud in the middle.
Bytebase
Devops
An open-source database CI/CD and DevSecOps platform — schema migration review, GitOps-driven changes, data masking, and access control across MySQL, PostgreSQL, Oracle, Snowflake, MongoDB, and more.
Cal.diy
Scheduling
The 100% MIT-licensed, community-driven scheduling platform — self-host your own booking infrastructure with no enterprise strings attached.
Cherry Studio
AI Assistants
All-in-one AI desktop client with 300+ assistants and multi-model support
cmux
Developer Tools · AI Development
A native, Ghostty-based macOS terminal with vertical tabs, agent-aware notifications, and a scriptable browser built for running many parallel AI coding agent sessions instead of juggling tmux panes.