# VirtualList

*Category:* Components
*Section:* Content
*Source:* https://uikit.developers.rio.cloud/#/components/virtualList
*Captured:* 2026-04-27T14:58:08.977Z

The VirtualList component is designed for efficiently rendering large lists of items by only displaying the visible portion of the list, also known as windowing.

## VirtualList

It allows a specified number of items outside the viewport for smoother scrolling. It optimizes performance by minimizing DOM updates and provides a customizable rendering function for each item, making it ideal for applications that require dynamic and responsive list displays.

### Example: Example 1

Virtual list with 100 items Item 1
In, In pharetra ante elementum ac nunc in Duis

Item 2
Efficitur efficitur elit. molestie faucibus. in, tortor volutpat Duis tincidunt. ante purus

Item 3
Libero fringilla ut ligula dolor ligula sit Vivamus semper posuere est quis, viverra in,

Item 4
Consectetur pharetra nunc efficitur volutpat

Item 5
In nec dui aliquam adipiscing metus

Item 6
Elit. eget ac quis, semper. sem.

Item 7
Ut finibus hendrerit aliquam amet, consectetur

Item 8
Primis ac et scelerisque aliquam Sed pharetra fames consectetur lorem in
Lorem velit. nunc

Item 9
Duis pretium orci, consectetur condimentum sit ante in posuere vel purus ante primis sem. nunc

Item 10
Efficitur purus pharetra faucibus. primis purus

#### React (tsx)

```tsx
import VirtualList from '@rio-cloud/rio-uikit/VirtualList';

import { generateDummyText } from '../../../utils/data';

const ITEM_COUNT = 100;

export default () => {
    const items = Array.from({ length: ITEM_COUNT }, (_, index) => ({
        title: `Item ${index + 1}`,
        description: generateDummyText(),
    }));

    return (
        <div className='max-width-600 padding-y-20'>
            <label className='padding-left-10'>Virtual list with {ITEM_COUNT} items</label>
            <VirtualList
                items={items}
                renderItem={(item, index) => (
                    <div
                        key={index}
                        className='margin-bottom-10 padding-y-10 padding-x-15 bg-white rounded shadow-accent text-color-darker'
                    >
                        <div className='text-medium' data-test-ignore='text'>
                            {item.title}
                        </div>
                        <div className='word-break' data-test-ignore='text'>
                            {item.description}
                        </div>
                    </div>
                )}
                className='max-height-400 padding-x-10'
            />
        </div>
    );
};
```

#### HTML (html)

```html
<div class="max-width-600 padding-y-20">
    <label class="padding-left-10">Virtual list with 100 items</label>
    <div class="VirtualList overflow-y-auto max-height-400 padding-x-10" style="height: 100%; position: relative; overflow: auto;">
        <div class="position-relative" style="height: 7200px;">
            <div class="VirtualListItemContainer ">
                <div class="VirtualListItemWrapper " data-index="0" style="position: absolute; transform: translateY(0px); width: 100%; will-change: transform;">
                    <div class="margin-bottom-10 padding-y-10 padding-x-15 bg-white rounded shadow-accent text-color-darker">
                        <div class="text-medium" data-test-ignore="text">Item 1</div>
                        <div class="word-break" data-test-ignore="text">In, In pharetra ante elementum ac nunc in Duis</div>
                    </div>
                </div>
                <div class="VirtualListItemWrapper " data-index="1" style="position: absolute; transform: translateY(70px); width: 100%; will-change: transform;">
                    <div class="margin-bottom-10 padding-y-10 padding-x-15 bg-white rounded shadow-accent text-color-darker">
                        <div class="text-medium" data-test-ignore="text">Item 2</div>
                        <div class="word-break" data-test-ignore="text">Efficitur efficitur elit. molestie faucibus. in, tortor volutpat Duis tincidunt. ante purus</div>
                    </div>
                </div>
                <div class="VirtualListItemWrapper " data-index="2" style="position: absolute; transform: translateY(140px); width: 100%; will-change: transform;">
                    <div class="margin-bottom-10 padding-y-10 padding-x-15 bg-white rounded shadow-accent text-color-darker">
                        <div class="text-medium" data-test-ignore="text">Item 3</div>
                        <div class="word-break" data-test-ignore="text">Libero fringilla ut ligula dolor ligula sit Vivamus semper posuere est quis, viverra in,</div>
                    </div>
                </div>
                <div class="VirtualListItemWrapper " data-index="3" style="position: absolute; transform: translateY(210px); width: 100%; will-change: transform;">
                    <div class="margin-bottom-10 padding-y-10 padding-x-15 bg-white rounded shadow-accent text-color-darker">
                        <div class="text-medium" data-test-ignore="text">Item 4</div>
                        <div class="word-break" data-test-ignore="text">Consectetur pharetra nunc efficitur volutpat</div>
                    </div>
                </div>
                <div class="VirtualListItemWrapper " data-index="4" style="position: absolute; transform: translateY(280px); width: 100%; will-change: transform;">
                    <div class="margin-bottom-10 padding-y-10 padding-x-15 bg-white rounded shadow-accent text-color-darker">
                        <div class="text-medium" data-test-ignore="text">Item 5</div>
                        <div class="word-break" data-test-ignore="text">In nec dui aliquam adipiscing metus</div>
                    </div>
                </div>
                <div class="VirtualListItemWrapper " data-index="5" style="position: absolute; transform: translateY(350px); width: 100%; will-change: transform;">
                    <div class="margin-bottom-10 padding-y-10 padding-x-15 bg-white rounded shadow-accent text-color-darker">
                        <div class="text-medium" data-test-ignore="text">Item 6</div>
                        <div class="word-break" data-test-ignore="text">Elit. eget ac quis, semper. sem.</div>
                    </div>
                </div>
                <div class="VirtualListItemWrapper " data-index="6" style="position: absolute; transform: translateY(420px); width: 100%; will-change: transform;">
                    <div class="margin-bottom-10 padding-y-10 padding-x-15 bg-white rounded shadow-accent text-color-darker">
                        <div class="text-medium" data-test-ignore="text">Item 7</div>
                        <div class="word-break" data-test-ignore="text">Ut finibus hendrerit aliquam amet, consectetur</div>
                    </div>
                </div>
                <div class="VirtualListItemWrapper " data-index="7" style="position: absolute; transform: translateY(490px); width: 100%; will-change: transform;">
                    <div class="margin-bottom-10 padding-y-10 padding-x-15 bg-white rounded shadow-accent text-color-darker">
                        <div class="text-medium" data-test-ignore="text">Item 8</div>
                        <div class="word-break" data-test-ignore="text">Primis ac et scelerisque aliquam Sed pharetra fames consectetur lorem in
                            Lorem velit. nunc</div>
                    </div>
                </div>
                <div class="VirtualListItemWrapper " data-index="8" style="position: absolute; transform: translateY(560px); width: 100%; will-change: transform;">
                    <div class="margin-bottom-10 padding-y-10 padding-x-15 bg-white rounded shadow-accent text-color-darker">
                        <div class="text-medium" data-test-ignore="text">Item 9</div>
                        <div class="word-break" data-test-ignore="text">Duis pretium orci, consectetur condimentum sit ante in posuere vel purus ante primis sem. nunc</div>
                    </div>
                </div>
                <div class="VirtualListItemWrapper " data-index="9" style="position: absolute; transform: translateY(650px); width: 100%; will-change: transform;">
                    <div class="margin-bottom-10 padding-y-10 padding-x-15 bg-white rounded shadow-accent text-color-darker">
                        <div class="text-medium" data-test-ignore="text">Item 10</div>
                        <div class="word-break" data-test-ignore="text">Efficitur purus pharetra faucibus. primis purus</div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
```

#### Props

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| items | T[] | — | The array of items to be rendered in the list. |
| renderItem | (item: T, index: number) => React.ReactElement | — | A function that renders an item given its data and index. |
| overscanCount | number | 3 | The number of items to render outside the visible area for smoother scrolling. |
| defaultHeight | number | 50 | The default height for items if their height cannot be determined. |
| scrollContainerRef | React.RefObject<HTMLElement> | — | Optional ref to an external scroll container. Use this when VirtualList is inside a scrollable container. |
| containerClassName | string | — | Additional classNames for the container of the list items. |
| listItemWrapperClassName | string | — | Additional classNames for each individual list item wrapper. This wrapper is required for proper positioning each item in the list using an absolute top value. |
| className | string | — | Additional classNames for the outer list container |

### Example: Example 2

Virtual list with 5000 items
Vehicle 1
Felis. dolor et libero Vivamus massa, efficitur consectetur consectetur efficitur ligula elit. Interdum

Vehicle 2
Primis eget amet, est ante ante lorem bibendum, semper sem. elementum

Vehicle 3
Adipiscing tincidunt. est Vivamus eget nec

Vehicle 4
Et neque. metus ac efficitur hendrerit

Vehicle 5
Neque. Mauris malesuada tincidunt. Mauris condimentum

Vehicle 6
Ut massa ante ante nunc ipsum et

Vehicle 7
Sed primis eget ligula in, purus vitae in orci pharetra

Vehicle 8
Adipiscing et rutrum neque. fringilla

Vehicle 9
Condimentum efficitur Mauris in dui faucibus. rutrum

Vehicle 10
Viverra massa, ante felis. Sed ut ligula volutpat

#### React (tsx)

```tsx
import { useRef } from 'react';

import Avatar from '@rio-cloud/rio-uikit/Avatar';
import VirtualList from '@rio-cloud/rio-uikit/VirtualList';

import { generateDummyText } from '../../../utils/data';

const DemoItem = ({ title, description }: { title: string; description: string }) => (
    <div className='display-flex gap-15 align-items-center'>
        <Avatar iconName='truck' backgroundColor='bg-lightest' />
        <div>
            <div className='text-medium' data-test-ignore='text'>
                {title}
            </div>
            <div className='word-break' data-test-ignore='text'>
                {description}
            </div>
        </div>
    </div>
);

const ITEM_COUNT = 5_000;

// This demo includes:
// - A custom item component
// - List group styling for the inner container and the items wrapper
// - The max height is defined outside on the parent of the VirtualList using a scrollContainerRef
// - A custom overscan count, means more items are loaded outside the visible window

export default () => {
    const items = Array.from({ length: ITEM_COUNT }, (_, index) => ({
        title: `Vehicle ${index + 1}`,
        description: generateDummyText(),
    }));

    const scrollContainerRef = useRef<HTMLDivElement>(null);

    return (
        <div className='padding-20'>
            <label>Virtual list with {ITEM_COUNT} items</label>
            <div ref={scrollContainerRef} className='max-width-600 max-height-400 overflow-y-auto'>
                <VirtualList
                    items={items}
                    renderItem={(item, index) => (
                        <DemoItem key={index} title={item.title} description={item.description} />
                    )}
                    className='border rounded'
                    containerClassName='list-group'
                    listItemWrapperClassName='list-group-item padding-y-15'
                    defaultHeight={71}
                    overscanCount={5}
                    scrollContainerRef={scrollContainerRef}
                />
            </div>
        </div>
    );
};
```

#### HTML (html)

```html
<div class="padding-20">
    <label>Virtual list with 5000 items</label>
    <div class="max-width-600 max-height-400 overflow-y-auto">
        <div class="VirtualList overflow-y-auto border rounded" style="height: 360000px; position: relative; overflow: visible;">
            <div class="position-relative" style="height: auto;">
                <div class="VirtualListItemContainer list-group">
                    <div class="VirtualListItemWrapper list-group-item padding-y-15" data-index="0" style="position: absolute; transform: translateY(0px); width: 100%; will-change: transform;">
                        <div class="display-flex gap-15 align-items-center">
                            <div class="Avatar bg-lightest" style="height: 40px;">
                                <span class="Avatar-icon rioglyph rioglyph-truck ">
                                </span>
                            </div>
                            <div>
                                <div class="text-medium" data-test-ignore="text">Vehicle 1</div>
                                <div class="word-break" data-test-ignore="text">Felis. dolor et libero Vivamus massa, efficitur consectetur consectetur efficitur ligula elit. Interdum</div>
                            </div>
                        </div>
                    </div>
                    <div class="VirtualListItemWrapper list-group-item padding-y-15" data-index="1" style="position: absolute; transform: translateY(89px); width: 100%; will-change: transform;">
                        <div class="display-flex gap-15 align-items-center">
                            <div class="Avatar bg-lightest" style="height: 40px;">
                                <span class="Avatar-icon rioglyph rioglyph-truck ">
                                </span>
                            </div>
                            <div>
                                <div class="text-medium" data-test-ignore="text">Vehicle 2</div>
                                <div class="word-break" data-test-ignore="text">Primis eget amet, est ante ante lorem bibendum, semper sem. elementum</div>
                            </div>
                        </div>
                    </div>
                    <div class="VirtualListItemWrapper list-group-item padding-y-15" data-index="2" style="position: absolute; transform: translateY(159px); width: 100%; will-change: transform;">
                        <div class="display-flex gap-15 align-items-center">
                            <div class="Avatar bg-lightest" style="height: 40px;">
                                <span class="Avatar-icon rioglyph rioglyph-truck ">
                                </span>
                            </div>
                            <div>
                                <div class="text-medium" data-test-ignore="text">Vehicle 3</div>
                                <div class="word-break" data-test-ignore="text">Adipiscing tincidunt. est Vivamus eget nec</div>
                            </div>
                        </div>
                    </div>
                    <div class="VirtualListItemWrapper list-group-item padding-y-15" data-index="3" style="position: absolute; transform: translateY(229px); width: 100%; will-change: transform;">
                        <div class="display-flex gap-15 align-items-center">
                            <div class="Avatar bg-lightest" style="height: 40px;">
                                <span class="Avatar-icon rioglyph rioglyph-truck ">
                                </span>
                            </div>
                            <div>
                                <div class="text-medium" data-test-ignore="text">Vehicle 4</div>
                                <div class="word-break" data-test-ignore="text">Et neque. metus ac efficitur hendrerit</div>
                            </div>
                        </div>
                    </div>
                    <div class="VirtualListItemWrapper list-group-item padding-y-15" data-index="4" style="position: absolute; transform: translateY(299px); width: 100%; will-change: transform;">
                        <div class="display-flex gap-15 align-items-center">
                            <div class="Avatar bg-lightest" style="height: 40px;">
                                <span class="Avatar-icon rioglyph rioglyph-truck ">
                                </span>
                            </div>
                            <div>
                                <div class="text-medium" data-test-ignore="text">Vehicle 5</div>
                                <div class="word-break" data-test-ignore="text">Neque. Mauris malesuada tincidunt. Mauris condimentum</div>
                            </div>
                        </div>
                    </div>
                    <div class="VirtualListItemWrapper list-group-item padding-y-15" data-index="5" style="position: absolute; transform: translateY(369px); width: 100%; will-change: transform;">
                        <div class="display-flex gap-15 align-items-center">
                            <div class="Avatar bg-lightest" style="height: 40px;">
                                <span class="Avatar-icon rioglyph rioglyph-truck ">
                                </span>
                            </div>
                            <div>
                                <div class="text-medium" data-test-ignore="text">Vehicle 6</div>
                                <div class="word-break" data-test-ignore="text">Ut massa ante ante nunc ipsum et</div>
                            </div>
                        </div>
                    </div>
                    <div class="VirtualListItemWrapper list-group-item padding-y-15" data-index="6" style="position: absolute; transform: translateY(439px); width: 100%; will-change: transform;">
                        <div class="display-flex gap-15 align-items-center">
                            <div class="Avatar bg-lightest" style="height: 40px;">
                                <span class="Avatar-icon rioglyph rioglyph-truck ">
                                </span>
                            </div>
                            <div>
                                <div class="text-medium" data-test-ignore="text">Vehicle 7</div>
                                <div class="word-break" data-test-ignore="text">Sed primis eget ligula in, purus vitae in orci pharetra</div>
                            </div>
                        </div>
                    </div>
                    <div class="VirtualListItemWrapper list-group-item padding-y-15" data-index="7" style="position: absolute; transform: translateY(509px); width: 100%; will-change: transform;">
                        <div class="display-flex gap-15 align-items-center">
                            <div class="Avatar bg-lightest" style="height: 40px;">
                                <span class="Avatar-icon rioglyph rioglyph-truck ">
                                </span>
                            </div>
                            <div>
                                <div class="text-medium" data-test-ignore="text">Vehicle 8</div>
                                <div class="word-break" data-test-ignore="text">Adipiscing et rutrum neque. fringilla</div>
                            </div>
                        </div>
                    </div>
                    <div class="VirtualListItemWrapper list-group-item padding-y-15" data-index="8" style="position: absolute; transform: translateY(579px); width: 100%; will-change: transform;">
                        <div class="display-flex gap-15 align-items-center">
                            <div class="Avatar bg-lightest" style="height: 40px;">
                                <span class="Avatar-icon rioglyph rioglyph-truck ">
                                </span>
                            </div>
                            <div>
                                <div class="text-medium" data-test-ignore="text">Vehicle 9</div>
                                <div class="word-break" data-test-ignore="text">Condimentum efficitur Mauris in dui faucibus. rutrum</div>
                            </div>
                        </div>
                    </div>
                    <div class="VirtualListItemWrapper list-group-item padding-y-15" data-index="9" style="position: absolute; transform: translateY(649px); width: 100%; will-change: transform;">
                        <div class="display-flex gap-15 align-items-center">
                            <div class="Avatar bg-lightest" style="height: 40px;">
                                <span class="Avatar-icon rioglyph rioglyph-truck ">
                                </span>
                            </div>
                            <div>
                                <div class="text-medium" data-test-ignore="text">Vehicle 10</div>
                                <div class="word-break" data-test-ignore="text">Viverra massa, ante felis. Sed ut ligula volutpat</div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
```

#### Props

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| items | T[] | — | The array of items to be rendered in the list. |
| renderItem | (item: T, index: number) => React.ReactElement | — | A function that renders an item given its data and index. |
| overscanCount | number | 3 | The number of items to render outside the visible area for smoother scrolling. |
| defaultHeight | number | 50 | The default height for items if their height cannot be determined. |
| scrollContainerRef | React.RefObject<HTMLElement> | — | Optional ref to an external scroll container. Use this when VirtualList is inside a scrollable container. |
| containerClassName | string | — | Additional classNames for the container of the list items. |
| listItemWrapperClassName | string | — | Additional classNames for each individual list item wrapper. This wrapper is required for proper positioning each item in the list using an absolute top value. |
| className | string | — | Additional classNames for the outer list container |