Skip to content

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

License

Notifications You must be signed in to change notification settings

humanspeak/svelte-virtual-list

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

@humanspeak/svelte-virtual-list

NPM version Build Status Coverage Status License Downloads CodeQL Code Style: Trunk TypeScript Types Maintenance

A high-performance virtual list component for Svelte 5 applications that efficiently renders large datasets with minimal memory usage.

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
  • πŸ“ 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
  • 🧠 Memory-optimized for 10k+ items
  • πŸ§ͺ Comprehensive test coverage (vitest and playwright)
  • πŸš€ Progressive initialization for large datasets

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>

Advanced Features

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>

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

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

License

MIT Β© Humanspeak, Inc.

Credits

Made with β™₯ by Humanspeak