Headless UI for virtualizing scrollable elements in React
npx @tessl/cli install tessl/npm-tanstack--react-virtual@3.13.00
# TanStack React Virtual
1
2
TanStack React Virtual is a headless UI library for virtualizing scrollable elements in React. It enables efficient rendering of large lists and grids by only rendering visible items in the DOM, providing smooth scrolling performance and minimal memory footprint for data-heavy applications.
3
4
## Package Information
5
6
- **Package Name**: @tanstack/react-virtual
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**: `npm install @tanstack/react-virtual`
10
11
## Core Imports
12
13
```typescript
14
import {
15
useVirtualizer,
16
useWindowVirtualizer,
17
Virtualizer,
18
// Types
19
VirtualItem,
20
VirtualizerOptions,
21
Rect,
22
Range,
23
ScrollToOptions,
24
ScrollAlignment,
25
ScrollBehavior,
26
Key,
27
// Utility functions
28
defaultKeyExtractor,
29
defaultRangeExtractor,
30
observeElementRect,
31
observeElementOffset,
32
observeWindowRect,
33
observeWindowOffset,
34
elementScroll,
35
windowScroll,
36
measureElement,
37
// Advanced utilities
38
memo,
39
notUndefined,
40
approxEqual,
41
debounce,
42
PartialKeys,
43
NoInfer
44
} from "@tanstack/react-virtual";
45
```
46
47
For CommonJS:
48
49
```javascript
50
const {
51
useVirtualizer,
52
useWindowVirtualizer,
53
Virtualizer,
54
VirtualItem,
55
defaultKeyExtractor,
56
defaultRangeExtractor,
57
// ... other exports
58
} = require("@tanstack/react-virtual");
59
```
60
61
## Basic Usage
62
63
```typescript
64
import React from 'react';
65
import { useVirtualizer } from '@tanstack/react-virtual';
66
67
function VirtualList() {
68
const parentRef = React.useRef<HTMLDivElement>(null);
69
70
const virtualizer = useVirtualizer({
71
count: 10000,
72
getScrollElement: () => parentRef.current,
73
estimateSize: () => 35,
74
});
75
76
return (
77
<div
78
ref={parentRef}
79
style={{
80
height: `400px`,
81
overflow: 'auto',
82
}}
83
>
84
<div
85
style={{
86
height: `${virtualizer.getTotalSize()}px`,
87
width: '100%',
88
position: 'relative',
89
}}
90
>
91
{virtualizer.getVirtualItems().map((virtualItem) => (
92
<div
93
key={virtualItem.key}
94
style={{
95
position: 'absolute',
96
top: 0,
97
left: 0,
98
width: '100%',
99
height: `${virtualItem.size}px`,
100
transform: `translateY(${virtualItem.start}px)`,
101
}}
102
data-index={virtualItem.index}
103
>
104
Row {virtualItem.index}
105
</div>
106
))}
107
</div>
108
</div>
109
);
110
}
111
```
112
113
## Architecture
114
115
TanStack React Virtual is built around several key components:
116
117
- **React Hooks**: `useVirtualizer` and `useWindowVirtualizer` provide React-specific virtualization functionality
118
- **Core Engine**: `Virtualizer` class handles all virtualization logic including measurement, scrolling, and range calculation
119
- **Observer System**: Built-in ResizeObserver integration for dynamic sizing and responsive behavior
120
- **Measurement Modes**: Supports fixed, variable, and dynamic item sizes with automatic measurement
121
- **Grid Layout**: Multi-lane support for grid virtualization with customizable lane counts
122
- **Scroll Management**: Imperative scrolling APIs with alignment options and smooth scroll support
123
124
## Capabilities
125
126
### React Virtualization Hooks
127
128
React-specific hooks that provide virtualized scrolling for elements and windows with automatic state management and optimal re-rendering.
129
130
```typescript { .api }
131
function useVirtualizer<TScrollElement extends Element, TItemElement extends Element>(
132
options: PartialKeys<VirtualizerOptions<TScrollElement, TItemElement>, 'observeElementRect' | 'observeElementOffset' | 'scrollToFn'>
133
): Virtualizer<TScrollElement, TItemElement>;
134
135
function useWindowVirtualizer<TItemElement extends Element>(
136
options: PartialKeys<VirtualizerOptions<Window, TItemElement>, 'getScrollElement' | 'observeElementRect' | 'observeElementOffset' | 'scrollToFn'>
137
): Virtualizer<Window, TItemElement>;
138
```
139
140
[React Hooks](./react-hooks.md)
141
142
### Virtualizer Core Engine
143
144
The core virtualization engine class that manages all aspects of virtual scrolling including item measurement, range calculation, and scroll positioning.
145
146
```typescript { .api }
147
class Virtualizer<TScrollElement extends Element | Window, TItemElement extends Element> {
148
constructor(opts: VirtualizerOptions<TScrollElement, TItemElement>);
149
150
// Core methods
151
getVirtualItems(): Array<VirtualItem>;
152
scrollToIndex(index: number, options?: ScrollToIndexOptions): void;
153
scrollToOffset(toOffset: number, options?: ScrollToOffsetOptions): void;
154
getTotalSize(): number;
155
measureElement(node: TItemElement | null | undefined): void;
156
}
157
158
interface VirtualizerOptions<TScrollElement extends Element | Window, TItemElement extends Element> {
159
count: number;
160
getScrollElement: () => TScrollElement | null;
161
estimateSize: (index: number) => number;
162
scrollToFn: (offset: number, options: ScrollOptions, instance: Virtualizer<TScrollElement, TItemElement>) => void;
163
observeElementRect: (instance: Virtualizer<TScrollElement, TItemElement>, cb: (rect: Rect) => void) => void | (() => void);
164
observeElementOffset: (instance: Virtualizer<TScrollElement, TItemElement>, cb: (offset: number, isScrolling: boolean) => void) => void | (() => void);
165
// ... additional optional properties
166
}
167
```
168
169
[Virtualizer Engine](./virtualizer-engine.md)
170
171
### Types and Utilities
172
173
Core type definitions, interfaces, and utility functions used throughout the virtualization system.
174
175
```typescript { .api }
176
interface VirtualItem {
177
key: Key;
178
index: number;
179
start: number;
180
end: number;
181
size: number;
182
lane: number;
183
}
184
185
interface Rect {
186
width: number;
187
height: number;
188
}
189
190
interface Range {
191
startIndex: number;
192
endIndex: number;
193
overscan: number;
194
count: number;
195
}
196
```
197
198
[Types and Utilities](./types-utilities.md)
199
200
## Common Patterns
201
202
### Fixed Size Items
203
204
For lists with consistent item heights:
205
206
```typescript
207
const virtualizer = useVirtualizer({
208
count: items.length,
209
getScrollElement: () => parentRef.current,
210
estimateSize: () => 50, // Fixed height
211
});
212
```
213
214
### Dynamic Size Items
215
216
For lists with varying item heights:
217
218
```typescript
219
const virtualizer = useVirtualizer({
220
count: items.length,
221
getScrollElement: () => parentRef.current,
222
estimateSize: (index) => items[index]?.estimatedHeight ?? 50,
223
measureElement: (element, entry, instance) => {
224
// Custom measurement logic if needed
225
return element.offsetHeight;
226
},
227
});
228
```
229
230
### Grid Layout
231
232
For grid virtualization with multiple columns:
233
234
```typescript
235
const virtualizer = useVirtualizer({
236
count: items.length,
237
getScrollElement: () => parentRef.current,
238
estimateSize: () => 200,
239
lanes: 3, // 3-column grid
240
gap: 16, // Space between items
241
});
242
```
243
244
### Window Scrolling
245
246
For virtualizing content in the main window:
247
248
```typescript
249
const virtualizer = useWindowVirtualizer({
250
count: items.length,
251
estimateSize: () => 100,
252
overscan: 5,
253
});
254
```