# TanStack Virtual: a headless virtualizer for large lists in React, Vue, Svelte and Solid

> TanStack Virtual is a framework-agnostic headless virtualization library for rendering large lists, grids and tables while keeping control of the markup. It ships as a small core plus per-framework adapters, and it is maintained under the MIT licence.

**TanStack/virtual** — 🤖 Headless UI for Virtualizing Large Element Lists in JS/TS, React, Solid, Vue and Svelte

- Repository: https://github.com/TanStack/virtual
- Website: https://tanstack.com/virtual
- Stars: 7,126 · Forks: 470
- Language: TypeScript
- License: MIT
- Published: 2026-09-22 · Updated: 2026-09-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/tanstack-virtual

## The problem TanStack Virtual solves, and who it is for

Rendering ten thousand rows into the DOM is a browser problem before it is a framework problem. Each row costs layout, style calculation and memory, and the cost shows up as janky scrolling long before the dataset is unusual by backend standards. TanStack Virtual addresses that by computing which subset of items is visible and letting you render only those. The README describes the library as "headless, framework-agnostic" and aimed at "massive lists, grids, and tables", with the promise of "full control over markup and styles".

That word headless is the whole pitch. The library does not ship a list component, a row wrapper or a stylesheet. It gives you a hook or function that returns the virtual items plus the measurements needed to position them, and you write the container and the rows. Teams that already have a design system and a table component will find that attractive, because nothing has to be restyled or overridden. Teams that wanted a finished data grid will find it incomplete, and that is the correct reading of the project rather than a defect.

The intended audience is frontend engineers working in JavaScript or TypeScript who have an existing list or grid they cannot simply paginate away. The repository lists topics including react, solid, svelte, vue, virtualization and performance, and the examples directory contains separate folders for angular, lit, marko, react, svelte and vue, so the adapters go beyond the four frameworks named in the project description.

## How the virtualizer computes what to render

The mechanism is a scroll listener plus an arithmetic window. You give the virtualizer a count of items, an estimate of how large each item is, and a reference to the scrolling element. From the scroll offset and the viewport size it derives a start index and an end index, and exposes a list of virtual items. Each virtual item carries the offset and size you need to absolutely position it, plus the index it corresponds to so you can fetch the right data.

The interesting part is measurement. A fixed estimate is wrong the moment rows have variable height, so the library supports measured sizing, where the real size of a rendered element is read back and fed into the running totals. The README lists "dynamic & measured sizing support" among the features. This is also where the complexity lives: measurement is asynchronous relative to render, so the scroll height shifts as items are corrected, and the README does not document a rollback or a scroll-anchoring strategy for that correction. If your rows change height after mount, you own the consequences.

The README also mentions "sticky items and window-scrolling utilities", which covers two common cases: headers or grouped labels that stay pinned while their section scrolls, and virtualizing against the document scroll rather than an inner overflow container. Both are configuration of the same core rather than separate components.

The package layout follows the usual TanStack split. A framework-independent core holds the computation, and each framework package wraps it. Recent releases on npm include @tanstack/virtual-core, @tanstack/vue-virtual and @tanstack/svelte-virtual, all published on 2026-09-14, which confirms that the adapters are versioned separately from the core and can drift apart by a patch or minor version.

## Installing TanStack Virtual and rendering a first virtualized list

The README does not include installation or usage snippets of its own; it points to https://tanstack.com/virtual for the documentation and lists the packages published on npm. The adapter for React is published as @tanstack/react-virtual, and the repository ships runnable examples under examples/react, examples/vue, examples/svelte and the other framework folders, which is where the exact API surface for your version should be read.

The only command the repository itself documents for getting a working tree is the pnpm toolchain it pins in the root package.json: packageManager is pnpm@11.9.0 and engines requires pnpm >=11.9.0. The root scripts include build:all and dev, and CONTRIBUTING.md is the file the README points to for setup instructions.

```bash
pnpm run build:all
```

That command builds every package in the workspace except the examples, which is the step you need before the example apps can resolve the local adapters. The README's "Get Involved" section states that issues and pull requests are welcome and directs contributors to CONTRIBUTING.md, so the setup sequence beyond the pinned pnpm version lives there rather than in the README.

For application code, the shape of the API is a hook that takes a count, a size estimate and a scroll element reference, and returns virtual items with offsets and sizes that you position yourself. The README does not print that call, so treat the examples directory as the reference implementation and check the exported names against the version you install rather than copying a snippet from a blog post.

## Where TanStack Virtual is the wrong tool

The first limitation is that windowing does not reduce data cost. If your list is backed by an API that returns all ten thousand rows at once, virtualization fixes paint time and leaves network and parse time untouched. The library has no opinion about data loading, caching or pagination; that is a different TanStack package's job, and nothing in the README connects them for you.

The second is measurement. Estimated sizes that are consistently wrong produce a scrollbar that jumps as the user drags it, because the total height is recomputed from corrected items. The README presents measured sizing as a feature but does not document a scroll-anchoring or rollback mechanism for the correction, so variable-height content with images or expanded rows is the case to prototype before committing.

The third is accessibility and semantics. Because the library is headless, it renders nothing, which means keyboard navigation, focus management and ARIA roles on a virtualized list are entirely yours. A virtualized list that unmounts offscreen rows also unmounts their focusable children, and no part of the library prevents that. If your list is a form, a menu or anything with sequential focus, windowing is working against you.

Finally, the headless design is a poor fit for teams that want a finished grid. Sorting, filtering, column resizing, pinned columns and cell editing are not in scope here. TanStack Table is listed in the README's ecosystem section as the headless datagrid sibling, and combining the two is a deliberate integration rather than a default.

## How it differs from react-window and react-virtuoso

The closest comparison in the React ecosystem is react-window, which also virtualizes lists and grids without owning your styles. The difference in approach is the API shape and the sizing model. react-window exposes components such as FixedSizeList and VariableSizeList, so you pick a component that matches your sizing strategy and the component owns the outer element and the positioning of children. TanStack Virtual exposes a hook that returns data, and you own every element. That is a real trade-off: react-window gets you to a working list with less code, while TanStack Virtual lets you put the scroll container anywhere in an existing layout and reuse your own row component untouched.

react-virtuoso sits further toward batteries included, handling measurement and a number of list behaviours internally. If you want the library to solve variable heights for you, that is the direction to look. TanStack Virtual's answer is to give you the measured size and let you decide what to do when it changes.

The second difference is framework reach. react-window and react-virtuoso are React-only. TanStack Virtual ships adapters for React, Vue, Svelte and Solid, and the repository's examples directory also contains angular, lit and marko folders. If your organisation runs more than one framework, sharing the mental model of one virtualizer is worth more than the per-framework ergonomics of three separate libraries.

## Maintenance, versioning and the MIT licence

The repository is not archived, and its last push was on 2026-09-21, one day before the date of writing. The most recent npm releases listed are @tanstack/vue-virtual@3.13.39, @tanstack/virtual-core@3.17.11 and @tanstack/svelte-virtual@3.13.39, all published on 2026-09-14. The core and the adapters are on different minor versions, which is normal for this layout but means an upgrade is two decisions rather than one.

Release management is visible in the repository root. There is a .changeset directory and the root package.json defines changeset, changeset:version and changeset:publish scripts, so versions are cut through Changesets rather than hand-edited. The same file pins the toolchain: packageManager is pnpm@11.9.0, engines requires pnpm >=11.9.0, and the test and build targets run through nx with separate targets for lib, types, e2e, eslint, knip and docs link verification. For a consumer this matters in one narrow way: if you want to run the repository's own examples, you need pnpm 11.9.0 or newer, not npm or yarn.

The licence is MIT, as stated in the repository and its LICENSE file. That permits commercial use and modification with the copyright notice retained; it also means there is no warranty and no support obligation from the maintainers. Nothing in the README or the repository metadata describes a paid tier, a commercial licence or a support contract, so the upgrade cost is best estimated as the cost of following Changesets releases and re-checking the adapter version you depend on. For legal questions about redistribution, the LICENSE file is the source to read, not this article.

## Conclusion

Adopt TanStack Virtual if you already own the markup and styles for your list and just need the windowing math, and if you are on React, Vue, Svelte, Solid, Angular, Lit or Marko, since the repository ships examples for each. Do not adopt it if you want a rendered grid with headers, pinned columns and editing out of the box, or if you cannot measure item heights and cannot accept estimated sizes. Before committing, verify three things in your own app: that dynamic measurement behaves with your real content, that the package version you install matches the framework adapter you import, and that the scrolling container you pass is the one that actually scrolls. The MIT licence is the only licensing term stated in the repository, and the repository was pushed on 2026-09-21.

## FAQ

### What is TanStack Virtual and what problem does it solve?

It is a headless, framework-agnostic virtualization library for rendering large lists, grids and tables. It computes which items are visible and returns them, so you render only that subset while keeping full control of the markup and styles.

### How do I install TanStack Virtual for React?

The adapter for React is published on npm as @tanstack/react-virtual, and the README points to https://tanstack.com/virtual for the documentation. The repository ships runnable examples under examples/react that show the API in use.

### Does TanStack Virtual render any markup or styles of its own?

No. The README describes it as headless, so it returns virtual items with offsets and sizes and you write the container, the rows and the styles yourself.

### Can TanStack Virtual handle rows with different heights?

Yes, the README lists dynamic and measured sizing support, where the real size of a rendered element is fed back into the running totals. The README does not document rollback or scroll anchoring for the correction, so variable-height content is the case to test first.

### Which frameworks does TanStack Virtual support?

The project description names React, Solid, Vue and Svelte, and the repository's examples directory also contains folders for angular, lit and marko. Each framework has its own adapter package, such as @tanstack/vue-virtual or @tanstack/svelte-virtual.

## Sources

- [License: MIT](https://github.com/TanStack/virtual/blob/main/LICENSE)
- [Project website](https://tanstack.com/virtual)
- [README](https://github.com/TanStack/virtual/blob/main/README.md)
- [Releases](https://github.com/TanStack/virtual/releases)
- [TanStack/virtual on GitHub](https://github.com/TanStack/virtual)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/tanstack-virtual
