Virtual List

Renders only visible items using fixed-height windowing. Perfect for large lists, chat feeds, and infinite scrolling.

Install

npx @vultra/cli add virtual-list

Usage

<script>
  import { VirtualList } from '@vultra/ui';

  const items = Array.from({ length: 10000 }, (_, i) => ({
    id: i,
    label: `Item ${i}`
  }));
</script>

<VirtualList {items} itemHeight={48} class="h-96">
  {#snippet children({ item })}
    <div class="flex h-full items-center border-b px-4">
      {item.label}
    </div>
  {/snippet}
</VirtualList>

Props

PropTypeDefaultDescription
itemsany[][]List data (bindable)
itemHeightnumber48Fixed row height (px)
overscannumber5Extra rows rendered outside viewport
onEndReached() => void-Load more at bottom
classstring-Container classes

Features

  • Renders only visible items (windowing)
  • Handles 10K+ items smoothly
  • onEndReached for infinite loading
  • Scrollable container (set height via class)

Example: Infinite Feed

<script>
  import { VirtualList } from '@vultra/ui';
  
  let items = $state([]);
  let page = $state(0);
  
  function loadMore() {
    page++;
    const next = Array.from({ length: 100 }, (_, i) => ({
      id: items.length + i,
      label: `Item ${items.length + i}`
    }));
    items = [...items, ...next];
  }
</script>

<VirtualList {items} itemHeight={48} onEndReached={loadMore} class="h-screen">
  {#snippet children({ item })}
    <div class="border-b px-4 py-2">{item.label}</div>
  {/snippet}
</VirtualList>