Virtual list
Windows large fixed-height collections while preserving focused rows.
Preview
Record 1
Record 2
Record 3
Record 4
Record 5
Record 6
Record 7
Record 8
Record 9
Record 10
Record 11
Record 12
Record 13
Record 14
In action
Record 1
Record 2
Record 3
Record 4
Record 5
Record 6
Record 7
Record 8
Record 9
Record 10
Record 11
Record 12
Record 13
Record 14
When to use
Use it for
- Large collections where fixed-height rows are an acceptable constraint.
Not for
- Short lists or variable-height content without a fixed row contract.
Install
Three ways in. They share one source, so the pixels match whichever you pick.
1. Import the package
npm install @noorddev/vlak-react
// once, next to your app's root
import "@noorddev/vlak-react/css";
import { VirtualList } from "@noorddev/vlak-react";Precompiled React and one stylesheet. No compiler to configure. Per-component imports work too: @noorddev/vlak-react/components/virtual-list.
2. Vendor the source
npx @noorddev/vlak-cli add virtual-list
The StyleX leaf lands in components/vlak/, for your own compiler to own. See StyleX.
3. Through shadcn
npx shadcn add https://vlak.dev/r/virtual-list.json
The same registry item, installed by shadcn's CLI.
CSS only
<link rel="stylesheet" href="node_modules/@noorddev/vlak/css/vlak.css" />
No React. Link vlak.css and use the markup and classes below.
React
import { VirtualList } from "@noorddev/vlak-react";
<VirtualList label="Records" height={264} items={Array.from({ length: 200 }, (_, index) => ({ id: String(index), label: `Record ${index + 1}` }))} />Props
VirtualList
Fixed-height windowing with a retained focused row and keyboard navigation.
| Prop | Type | Default | Description |
|---|---|---|---|
itemsrequired | VirtualItem[] | ||
labelrequired | string | ||
rowHeight | number | 44 | Fixed row height, at least 44px. |
height | number | 352 | |
overscan | number | 4 | |
emptyLabel | string | "No items" |
Also accepts HTMLAttributes<HTMLDivElement>.
Keyboard
| Keys | Does |
|---|---|
| Tab, Arrow up/down, Home, End | A row enters the Tab sequence; arrows and Home/End scroll and focus rows. Nested controls keep their own keys. |
Accessibility
- List items expose total size and position. Focused rows are retained when outside the visible window.
Markup
<div class="rs-virtual-list" role="list" aria-label="Records" style="height:264px"><div class="rs-virtual-list-canvas" role="none" style="height:44px"><div class="rs-virtual-list-item" role="listitem" tabindex="0" aria-posinset="1" aria-setsize="1" style="height:44px">Record 1</div></div></div>
Classes
.rs-virtual-list.rs-virtual-list-canvas.rs-virtual-list-item.rs-virtual-list-empty