svelte-virtual-list Svelte Themes

Svelte Virtual List

📜 A performant virtual list/scrolling component for Svelte applications - efficiently render large scrollable lists with minimal memory usage

Svelte Virtual List

A virtual list component for Svelte applications. Built for Svelte 5 with TypeScript support.

Features

  • Efficient rendering of large lists with dynamic heights
  • Bi-directional scrolling (top-to-bottom and bottom-to-top)
  • Automatic resize handling and content updates
  • TypeScript support with full type safety
  • SSR compatible with hydration support
  • Svelte 5 runes and snippets support
  • Customizable styling with class props
  • Debug mode for development
  • Smooth scrolling with configurable buffer zones

Installation

npm install @humanspeak/svelte-virtual-list

Basic Usage

<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>

Props

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

Dependencies

  • esm-env - svelte5 suggested environment detecting

Usage

<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>

Development

npm install
npm run dev

Testing

npm run test

Building

npm run build

License

MIT

Key Features

  • Dynamic item height handling - no fixed height required
  • Bi-directional scrolling support (top-to-bottom and bottom-to-top)
  • Automatic resize handling for dynamic content
  • Efficient rendering of large lists
  • TypeScript support
  • Customizable styling
  • Debug mode for development
  • Smooth scrolling with buffer zones
  • SSR compatible
  • Svelte 5 runes support

Usage Examples

Basic Usage

Default display

<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>

Bottom-to-Top Scrolling

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>

Advanced Features

Auto-resize Handling

The component automatically handles:

  • Dynamic content changes within items
  • Window resize events
  • Container resize events
  • Dynamic height calculations

No manual intervention is needed when item contents or dimensions change.

Advanced Usage

Chat Application Example

<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>

Performance Considerations

  • The bufferSize prop affects memory usage and scroll smoothness
  • Items are measured and cached for optimal performance
  • Dynamic height calculations happen automatically
  • Resize observers handle container/content changes
  • Virtual DOM updates are batched for efficiency
  • Svelte - JavaScript front-end framework

Made with ♥ by Humanspeak

Top categories

svelte logo

Need a Svelte website built?

Hire a professional Svelte developer today.
Loading Svelte Themes