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 Install size 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
  • πŸ•ΉοΈ Programmatic scrolling with scroll

scroll: Programmatic Scrolling

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!

Usage Example

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

API

  • scroll(options: { index: number; smoothScroll?: boolean; shouldThrowOnBounds?: boolean; align?: 'auto' | 'top' | 'bottom' })
    • 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) scrolls only if the item is out of view, aligning to top or bottom as needed. 'top' always aligns to the top, 'bottom' always aligns to the bottom.

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

About

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

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

 

Packages

No packages published