A virtual list component for Svelte applications. Built for Svelte 5 with TypeScript support.
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>
Prop | Type | Default | Description |
---|---|---|---|
items |
T[] |
Required | Array of items to render |
defaultItemHeight |
number |
40 |
Initial height for items before measurement |
mode |
'topToBottom' | 'bottomToTop' |
'topToBottom' |
Scroll direction |
bufferSize |
number |
20 |
Number of items to render outside 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 |
<script lang="ts">
import SvelteVirtualList from '@humanspeak/svelte-virtual-list'
import { onMount } from 'svelte'
type Item = {
id: number
text: string
}
const items: Item[] = Array.from({ length: 10000 }, (_, i) => ({
id: i,
text: `Item ${i}`
}))
</script>
<div class="grid grid-cols-2 gap-8">
<!-- Top to bottom scrolling -->
<div>
<SvelteVirtualList {items}>
{#snippet renderItem(item: Item, index: number)}
<div>
{item.text}
</div>
{/snippet}
</SvelteVirtualList>
</div>
<!-- Bottom to top scrolling -->
<div>
<SvelteVirtualList {items} mode="bottomToTop">
{#snippet renderItem(item: Item, index: number)}
<div>
{item.text}
</div>
{/snippet}
</SvelteVirtualList>
</div>
</div>
npm install
npm run dev
npm run test
npm run build
<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>
The component supports reverse scrolling, which is useful for chat applications or logs:
<SvelteVirtualList {items} mode="bottomToTop">
{#snippet renderItem(item)}
<div>{item.text}</div>
{/snippet}
</SvelteVirtualList>
The component automatically handles:
No manual intervention is needed when item contents or dimensions change.
<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>
<style>
.message-container {
padding: 1rem;
border-radius: 0.5rem;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}
.timestamp {
font-size: 0.875rem;
color: #6b7280;
}
</style>
bufferSize
prop affects memory usage and scroll smoothnessMade with ♥ by Humanspeak