A high-performance virtual list component for Svelte 5 applications that efficiently renders large datasets with minimal memory usage.
scroll
You can now programmatically scroll to any item in the list using the scroll
method. This is useful for chat apps, jump-to-item navigation, and more. You can check the usage in src/routes/tests/scroll
. Thank you for the feature request!
<script lang="ts">
import SvelteVirtualList from '@humanspeak/svelte-virtual-list'
let listRef
const items = Array.from({ length: 10000 }, (_, i) => ({ id: i, text: `Item ${i}` }))
function goToItem5000() {
// Scroll to item 5000 with smooth scrolling and auto alignment
listRef.scroll({ index: 5000, smoothScroll: true, align: 'auto' })
}
</script>
<button on:click={goToItem5000}> Scroll to item 5000 </button>
<SvelteVirtualList {items} bind:this={listRef}>
{#snippet renderItem(item)}
<div>{item.text}</div>
{/snippet}
</SvelteVirtualList>
scroll(options: { index: number; smoothScroll?: boolean; shouldThrowOnBounds?: boolean; align?: 'auto' | 'top' | 'bottom' | 'nearest' })
index
: The item index to scroll to (0-based)smoothScroll
: If true, uses smooth scrolling (default: true)shouldThrowOnBounds
: If true, throws if index is out of bounds (default: true)align
: Where to align the item in the viewport:'auto'
(default): Only scroll if not visible, align to top or bottom as appropriate'top'
: Always align to the top'bottom'
: Always align to the bottom'nearest'
: Scroll as little as possible to bring the item into view (like native scrollIntoView({ block: 'nearest' }))<button on:click={() => listRef.scroll({ index: 5000, align: 'nearest' })}>
Scroll to item 5000 (nearest)
</button>
npm install @humanspeak/svelte-virtual-list
<script lang="ts">
import SvelteVirtualList from '@humanspeak/svelte-virtual-list'
const items = Array.from({ length: 1000 }, (_, i) => ({
id: i,
text: `Item ${i}`
}))
</script>
<SvelteVirtualList {items}>
{#snippet renderItem(item)}
<div>{item.text}</div>
{/snippet}
</SvelteVirtualList>
<script lang="ts">
import SvelteVirtualList from '@humanspeak/svelte-virtual-list'
type Message = {
id: number
text: string
timestamp: Date
}
const messages: Message[] = Array.from({ length: 100 }, (_, i) => ({
id: i,
text: `Message ${i}`,
timestamp: new Date()
}))
</script>
<div style="height: 500px;">
<SvelteVirtualList items={messages} mode="bottomToTop" debug>
{#snippet renderItem(message)}
<div class="message-container">
<p>{message.text}</p>
<span class="timestamp">
{message.timestamp.toLocaleString()}
</span>
</div>
{/snippet}
</SvelteVirtualList>
</div>
Use mode="bottomToTop"
for chat-like lists anchored to the bottom. Programmatic scrolling uses the same API as top-to-bottom lists:
<script lang="ts">
import SvelteVirtualList from '@humanspeak/svelte-virtual-list'
let listRef
const messages = Array.from({ length: 2000 }, (_, i) => ({ id: i, text: `Msg ${i}` }))
</script>
<SvelteVirtualList items={messages} mode="bottomToTop" bind:this={listRef} />
<button on:click={() => listRef.scroll({ index: messages.length - 1, align: 'bottom' })}>
Jump to latest
</button>
Prop | Type | Default | Description |
---|---|---|---|
items |
T[] |
Required | Array of items to render |
defaultEstimatedItemHeight |
number |
40 |
Initial height estimate used until items are measured |
mode |
'topToBottom' | 'bottomToTop' |
'topToBottom' |
Scroll direction and anchoring behavior |
bufferSize |
number |
20 |
Number of items rendered outside the viewport |
debug |
boolean |
false |
Enable debug logging and visualizations |
containerClass |
string |
'' |
Class for outer container |
viewportClass |
string |
'' |
Class for scrollable viewport |
contentClass |
string |
'' |
Class for content wrapper |
itemsClass |
string |
'' |
Class for items container |
testId |
string |
'' |
Base test id used in internal test hooks (useful for E2E/tests and debugging) |
npm test
npx playwright install
npm run test:e2e
bufferSize
prop affects memory usage and scroll smoothnessMIT ยฉ Humanspeak, Inc.
Made with โฅ by Humanspeak