React Virtualized Data Grid

Fifty thousand rows in the DOM will freeze a browser; fifty in the DOM will not. This grid renders only the window you can see and repositions it as you scroll — the readout shows exactly which rows are live at any moment.

50,000 rows

rendering 24 · 024

0
L2400
1
0
0
Pass
0.462
94.9
1
L2400
2
1
0
Open
0.428
77.7
2
L2400
3
2
0
Open
0.459
11.8
3
L2400
4
3
0
Pass
0.409
4.5
4
L2400
5
4
0
Pass
0.397
95.3
5
L2400
6
5
0
Vt-high
0.401
27.8
6
L2400
7
6
0
Pass
0.404
23.2
7
L2400
8
7
0
Pass
0.458
13.2
8
L2400
9
8
0
Open
0.47
94
9
L2400
10
9
0
Pass
0.428
96.7
10
L2400
11
10
0
Pass
0.414
71
11
L2400
12
11
0
Short
0.46
23.6
12
L2400
13
12
0
Pass
0.392
41.9
13
L2400
14
13
0
Vt-high
0.422
21.7
14
L2400
15
14
0
Pass
0.447
61.6
15
L2400
16
15
0
Pass
0.41
72.5
16
L2400
17
16
0
Leak
0.422
36.6
17
L2400
18
17
0
Pass
0.394
71.9
18
L2400
19
18
0
Open
0.392
48.9
19
L2400
20
19
0
Short
0.426
34.1
20
L2400
21
20
0
Pass
0.427
17.7
21
L2400
22
21
0
Pass
0.496
39
22
L2400
23
22
0
Open
0.387
15.2
23
L2400
24
23
0
Pass
0.391
91.2

Installation

npx shadcn@latest add "https://kelvinui.com/registry/data-grid-virtual.json"

Props

PropTypeDescription
rowsT[]The full dataset — pass it all
columnsGridColumn<T>[]{ key, header, width?, align?, render?, sortValue?, sortable? }
rowKey(row: T) => string \number
rowHeightnumberFixed row height in px (default 36)
heightnumberViewport height in px (default 420)
overscannumberExtra rows rendered off-screen (default 6)
onRowClick(row: T) => voidRow click handler

How the windowing works

A single tall spacer, rows.length × rowHeight high, gives the scrollbar its full range. On scroll, the first visible index is floor(scrollTop / rowHeight); the grid slices a small band around it — plus overscan rows above and below so fast scrolling never flashes a blank edge — and positions each visible row absolutely at index × rowHeight. The DOM holds roughly twenty rows regardless of whether the dataset is fifty or fifty thousand.

The one constraint this buys performance with is a fixed row height. Variable heights need measured offsets and a very different implementation; if your rows genuinely differ in height, this is the wrong component. For tabular data — which is almost always uniform — the fixed height is the right trade, and sorting still operates over the entire dataset, not just the visible window.

New components every week

Get the week's new Kelvin UI components and templates in one short email. No spam, unsubscribe anytime.