Decorative background gradient
Back to Blog
TanStack Table ReactReact Table VirtualizationFast Large Dataset Rendering

TanStack Table React Virtualization: Fast Large Dataset Rendering

Render tens of thousands of rows without jank using TanStack Table v8 and react-virtual — infinite scroll, custom filters, and real performance gains.

TanStack Table React Virtualization: Fast Large Dataset Rendering

Rendering a table with a few hundred rows is trivial. Rendering one with 50,000+ rows — while keeping sorting, filtering, and smooth scrolling — is a completely different problem. TanStack Table gives you the headless logic; TanStack Virtual gives you the rendering performance. Together they let you build a data table that stays fast regardless of dataset size.

This guide builds a virtualized, infinitely-scrollable data table step by step.

Step 1: Set Up a Headless TanStack Table

TanStack Table doesn't render any markup — you define columns and it hands you row/column models to render however you want.

tsx

At this point rows could be 50 or 50,000 items — TanStack Table doesn't care, because it never touches the DOM.

Step 2: Virtualize the Rows

@tanstack/react-virtual only mounts the DOM nodes that are actually visible in the scroll container, plus a small overscan buffer.

tsx

The key mechanics: getTotalSize() gives the virtualizer's computed total scrollable height, and each row is absolutely positioned via translateY to its calculated offset. Only the rows returned by getVirtualItems() — typically 15-25 depending on viewport height — actually exist in the DOM at any moment, even if rows.length is 50,000.

Step 3: Add Infinite Scroll for Server-Paginated Data

Virtualization handles rendering; infinite scroll handles fetching more data as the user approaches the bottom. Combine the virtualizer's scroll position with useInfiniteQuery (TanStack Query):

tsx
tsx

This fetches the next 100-row page once the user scrolls within 20 rows of the currently loaded data, so new rows arrive before the user actually hits the bottom.

Step 4: Add Custom Filters Without Breaking Virtualization

Filtering happens entirely in TanStack Table's state layer — the virtualizer never needs to know about it.

tsx

Because rowVirtualizer is built from table.getRowModel().rows.length, filtering the underlying data automatically shrinks the virtualized row count — no manual synchronization required.

Performance in Practice

On a 50,000-row dataset, an un-virtualized table renders 50,000+ DOM nodes upfront — first paint alone can take several seconds and scrolling drops to single-digit frame rates. With virtualization, only ~20-30 rows ever exist in the DOM at once regardless of dataset size, so first paint stays under 100ms and scrolling holds a smooth 60fps because the browser is never asked to lay out more than a screenful of rows.

Common Pitfall: Row Height Drift Causes Scroll Jumps

If your estimateSize is a fixed value but actual row content varies in height (wrapped text, conditional badges), the virtualizer's positions will be slightly wrong until it measures real DOM heights. Always attach ref={rowVirtualizer.measureElement} to each row — it corrects the estimate after the first render and eliminates the jump.

Key Takeaways

TanStack Table's headless architecture is what makes true virtualization possible — it never dictates markup, so you can hand its row model straight to @tanstack/react-virtual and only render what's on screen. Layer infinite scroll on top with useInfiniteQuery, keep filtering in TanStack Table's state (the virtualizer picks it up automatically), and always measure real row heights to avoid scroll jitter.

Frequently Asked Questions

Is TanStack Table the same as react-table?

TanStack Table v8 is the successor to react-table v7, rebuilt to be framework-agnostic (React, Vue, Solid, Svelte adapters) and fully headless — it ships no markup or CSS, only table logic and state.

Why do I need a separate virtualization library?

TanStack Table computes rows, sorting, filtering, and pagination state, but it doesn't touch the DOM. Rendering 50,000 <tr> elements at once will freeze the browser regardless of how efficient the table logic is. @tanstack/react-virtual solves the rendering half by only mounting the rows currently in the viewport.

Can I combine virtualization with sorting and filtering?

Yes. Apply sorting/filtering through TanStack Table's state as normal — call table.getRowModel().rows to get the already sorted/filtered rows, then pass that array's length to the virtualizer. The virtualizer doesn't need to know about sorting or filtering at all.

How do I handle variable-height rows in a virtualized table?

Use the virtualizer's measureElement ref callback on each row instead of a fixed estimateSize. It measures actual rendered height after mount and recalculates virtual item positions, which prevents scroll position from jumping when row heights vary.

Working on something similar? Take a look at my services and case studies, or book a free call to talk about your idea.

Related Articles

Silent Tool Failures in AI Agents — Why Your Agent Lies About Success
Ai Agent ReliabilityTool Call FailuresLlm Error Handling+1 more

Silent Tool Failures in AI Agents — Why Your Agent Lies About Success

Most AI agent bugs never throw an error — the tool call "succeeds" with empty, truncated, or stale data and the agent confidently reports the task as done. Here's how to catch failures that don't look like failures.

September 22, 2026Read more →
AI Coding Agents Compared in 2026 — Claude Code vs Cursor vs GitHub Copilot
Claude Code Vs CursorAI Coding AgentsGithub Copilot

AI Coding Agents Compared in 2026 — Claude Code vs Cursor vs GitHub Copilot

Compare Claude Code, Cursor, and GitHub Copilot for real development work — agentic workflows, codebase understanding, pricing, and which fits your team.

September 18, 2026Read more →
Best Authentication Libraries for Next.js in 2026 — Clerk vs Auth.js vs Better Auth
Nextjs AuthenticationClerk Vs NextauthBetter Auth

Best Authentication Libraries for Next.js in 2026 — Clerk vs Auth.js vs Better Auth

Compare Clerk, Auth.js (NextAuth), and Better Auth for Next.js — setup effort, hosted UI, pricing, and which fits your app.

September 18, 2026Read more →
Best Error Monitoring & Analytics Tools for Next.js in 2026 — Sentry vs PostHog vs Vercel Analytics
Nextjs Error MonitoringSentry Vs PosthogWeb Analytics

Best Error Monitoring & Analytics Tools for Next.js in 2026 — Sentry vs PostHog vs Vercel Analytics

Compare Sentry, PostHog, and Vercel Analytics for a Next.js app — error tracking, product analytics, session replay, and pricing.

September 18, 2026Read more →
How to Add AI Features to an Existing Web App (Without a Rebuild)
Add AI To Existing AppAI SaaS FeaturesOpenAI API Integration

How to Add AI Features to an Existing Web App (Without a Rebuild)

A practical guide to adding real AI features, like matching, extraction, and automation, to a web app or SaaS product you already have, without rebuilding it from scratch.

September 16, 2026Read more →
AI Agent Observability and Tracing in Production
Ai Agent ObservabilityLlm TracingAgent Monitoring+2 more

AI Agent Observability and Tracing in Production

Why logging inputs and outputs isn't enough for AI agents in production — and how trace-level observability catches failures evals and logs miss.

September 14, 2026Read more →

Trending Topics