The Future of Web Dev
The Future of Web Dev
Tiny Virtual List Component for Svelte Apps
Improve Svelte app performance with this 5kb virtual list library. Render millions of items smoothly, support variable heights, and implement infinite scrolling.

svelte-tiny-virtual-list is a tiny yet powerful list virtualization library that renders only the items currently visible in the viewport, which significantly improves performance when working with extensive data sets.
This component reduces the initial load time and keeps scrolling smooth, even with datasets containing thousands or even millions of entries. It’s inspired by react-tiny-virtual-list and adapts its core concepts to the Svelte environment.
Features
📦 Tiny & Dependency-Free: The library is incredibly small (around 5kb gzipped) and has zero external dependencies.
↕️ Flexible Scrolling: Supports both vertical and horizontal list orientations.
📍 Scroll Control: You can programmatically scroll to a specific index or set an initial scroll offset.
🔑 Custom Keys: If items come from dynamic sources like databases, it allows you to use custom keys to uniquely identify them.
🚀 High Performance: Effortlessly handles massive datasets containing millions of items.
📏 Variable Item Sizes: Works with items of fixed or varying heights/widths.
📌 Sticky Items: Easily implement sticky elements within the list using the stickyIndices prop.
♾️ Infinite Loading Ready: Integrates with libraries like svelte-infinite-loading for dynamic data loading.
Use Cases
- E-commerce Product Listings: Imagine an online store with thousands of products. Instead of loading all product details and images at once, you can use
svelte-tiny-virtual-listto display only the products visible on the screen. This drastically reduces initial load times. - Social Media Feeds: Social media platforms often have infinitely scrolling feeds. This component, especially when combined with
svelte-infinite-loading, allows you to build a smooth, responsive feed that loads content as the user scrolls. - Large Data Tables: Displaying large datasets in a table format can be resource-intensive.
svelte-tiny-virtual-listhelps by rendering only the visible rows. This ensures a responsive user interface even with thousands of data entries. - Chat Applications: Chat applications with long message histories can benefit from list virtualization. Only the visible messages are rendered, keeping the application snappy.
Installation
Install the component using your preferred package manager:
With npm:
$ npm install svelte-tiny-virtual-listWith yarn:
$ yarn add svelte-tiny-virtual-listWith pnpm:
$ npm i -g pnpm
$ pnpm install svelte-tiny-virtual-listFor Sapper applications, install the package to devDependencies instead of dependencies to avoid potential issues.
The library also supports direct usage via CDN for projects that don’t use a build system:
<!-- UMD -->
<script src="https://unpkg.com/svelte-tiny-virtual-list@^1/dist/svelte-tiny-virtual-list.js"></script>
<!-- ES Module -->
<script src="https://unpkg.com/svelte-tiny-virtual-list@^1/dist/svelte-tiny-virtual-list.mjs"></script>Usage
Basic implementation requires minimal configuration. Here’s a simple example that renders a list of letters:
<script>
import VirtualList from 'svelte-tiny-virtual-list';
const data = ['A', 'B', 'C', 'D', 'E', 'F' /* ... */];
</script>
<VirtualList width="100%" height={600} itemCount={data.length} itemSize={50}>
<div slot="item" let:index let:style {style}>
Letter: {data[index]}, Row: #{index}
</div>
</VirtualList>The library works particularly well with infinite loading functionality:
<script>
import VirtualList from 'svelte-tiny-virtual-list';
import InfiniteLoading from 'svelte-infinite-loading';
let data = ['A', 'B', 'C', 'D', 'E', 'F' /* ... */];
function infiniteHandler({ detail: { complete, error } }) {
try {
// Fetch new data here
const newData = ['G', 'H', 'I', 'J', 'K', 'L' /* ... */];
data = [...data, ...newData];
complete();
} catch (e) {
error();
}
}
</script>
<VirtualList width="100%" height={600} itemCount={data.length} itemSize={50}>
<div slot="item" let:index let:style {style}>
Letter: {data[index]}, Row: #{index}
</div>
<div slot="footer">
<InfiniteLoading on:infinite={infiniteHandler} />
</div>
</VirtualList>For dynamic content sizes, you can use the recomputeSizes method to update the component when item dimensions change:
<script>
import { onMount } from 'svelte';
import VirtualList from 'svelte-tiny-virtual-list';
const data = ['A', 'B', 'C', 'D', 'E', 'F' /* ... */];
let virtualList;
function handleClick() {
virtualList.recomputeSizes(0);
}
</script>
<button on:click={handleClick}>Recompute Sizes</button>
<VirtualList
bind:this={virtualList}
width="100%"
height={600}
itemCount={data.length}
itemSize={50}
>
<div slot="item" let:index let:style {style}>
Letter: {data[index]}, Row: #{index}
</div>
</VirtualList>Related Resources
- svelte-virtual-list: Another virtualization library for Svelte. While not as tiny, it offers a different API. svelte-virtual-list
- react-tiny-virtual-list: The React library that inspired
svelte-tiny-virtual-list. If you’re familiar with React, this can provide additional context. react-tiny-virtual-list - Svelte Documentation: The official Svelte documentation is an excellent resource for learning about Svelte’s core concepts and features. Svelte Documentation
- svelte-infinite-loading: A library for implementing infinite scrolling, which pairs well with
svelte-tiny-virtual-list. svelte-infinite-loading
FAQs
Q: How does list virtualization improve performance?
A: List virtualization renders only the items currently visible in the viewport rather than the entire list. This significantly reduces DOM elements, memory usage, and processing time, resulting in smoother scrolling and better overall performance, especially for lists with thousands of items.
Q: What if my item heights are not all the same?
A: svelte-tiny-virtual-list supports variable item sizes. You can provide an array of heights or a function that returns the height for each item index.
Q: How do I handle dynamic data updates?
A: If your data changes and you are using a function for itemSize to provide individual item sizes, you should call the recomputeSizes() method on the VirtualList component to recalculate the layout. If you are using a number for a fixed item size it isn’t necessary to call the recomputeSizes() method.
Preview
