New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

usevirtualscroller

Package Overview
Dependencies
Maintainers
1
Versions
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

usevirtualscroller

vue-virtual-scroller is a tiny, TypeScript-friendly Vue 3 library that lets you render only the visible portion of very large lists. Just pass in your data array, container ref, and item height—no extra dependencies, no boilerplate—while enjoying smooth s

latest
npmnpm
Version
1.0.0
Version published
Weekly downloads
0
-100%
Maintainers
1
Weekly downloads
 
Created
Source

Vue 3 Virtual Scroller

vue-virtual-scroller is a tiny, TypeScript-friendly Vue 3 library that lets you render only the visible portion of very large lists. Just pass in your data array, container ref, and item height—no extra dependencies, no boilerplate—while enjoying smooth scrolling performance even on tens of thousands of items.

Installation

npm install vue-virtual-scroller

Usage Example

First, install:

yarn add vue-virtual-scroller
# or npm install vue-virtual-scroller

Then in your Vue 3 component:

<template>
  <div
          ref="scroller"
          class="scroller"
          @scroll.passive="onScroll"
  >
    <!-- top spacer -->
    <div :style="{ height: paddingTop + 'px' }" />

    <!-- only the visible items -->
    <div
            v-for="item in visibleItems"
            :key="item.id"
            class="item"
    >
      {{ item.label }}
    </div>

    <!-- bottom spacer -->
    <div :style="{ height: paddingBottom + 'px' }" />
  </div>
</template>

<script setup lang="ts">
  import { ref } from 'vue'
  import { useVirtualScroller } from 'vue-virtual-scroller'

  // 1. Your full data array:
  const items = Array.from({ length: 10000 }, (_, i) => ({
    id: i,
    label: `Item #${i}`,
  }))

  // 2. A ref to the scrolling container:
  const scroller = ref<HTMLElement | null>(null)

  // 3. Activate the scroller:
  const {
    visibleItems,
    paddingTop,
    paddingBottom,
    scrollToIndex,
  } = useVirtualScroller({
    items,
    containerRef: scroller,
    itemHeight: 30,    // each .item is 30px tall
    overscan: 5,       // render 5 extra items above & below
  })

  // (Optional) expose a method to jump to a particular item:
  function onScroll() {
    // you can also react to scroll events here
  }

  // e.g. somewhere in your code:
  // scrollToIndex(500)  // jump so item #500 is at the top
</script>

<style scoped>
  .scroller {
    height: 400px;
    overflow-y: auto;
    border: 1px solid #ddd;
  }

  .item {
    height: 30px;
    display: flex;
    align-items: center;
    padding: 0 8px;
    border-bottom: 1px solid #f0f0f0;
  }
</style>

How it works

  • paddingTop/paddingBottom keep the scroll bar size correct.
  • visibleItems is just the slice you render.
  • Adjust itemHeight and overscan to trade off between extra DOM nodes and scroll jank.

That’s it—drop the <div ref="scroller"> into your app anywhere you need high-performance lists!

API signature and options

import { Ref, ComputedRef } from 'vue'

export interface UseVirtualScrollerOptions<T> {
  /** The full array of items to virtualize */
  items: T[]
  /** A `ref` to your scrolling container element (overflow-auto/scroll) */
  containerRef: Ref<HTMLElement | null>
  /** Fixed height of a single item (in pixels) */
  itemHeight: number
  /**
   * Number of extra items to render above and below the viewport
   * @default 2
   */
  overscan?: number
}

export interface UseVirtualScrollerReturn<T> {
  /** The subset of `items` you should actually render */
  visibleItems: ComputedRef<T[]>
  /** Top spacer height in pixels */
  paddingTop: ComputedRef<number>
  /** Bottom spacer height in pixels */
  paddingBottom: ComputedRef<number>
  /** Index of the first rendered item */
  startIndex: ComputedRef<number>
  /** One past the index of the last rendered item */
  endIndex: ComputedRef<number>
  /** How many items fit in the container at once */
  visibleCount: ComputedRef<number>
  /** Scroll the container so that `index` lands at the top */
  scrollToIndex: (index: number) => void
}

/**
 * Creates a Vue composable for virtual‐scrolling a large list.
 *
 * @param options - Configuration options for virtualization
 * @returns an object with reactive fields and helpers
 */
export function useVirtualScroller<T>(
        options: UseVirtualScrollerOptions<T>
): UseVirtualScrollerReturn<T>

Options

OptionTypeRequiredDefaultDescription
itemsT[]The full data array you want to virtualize.
containerRefRef<HTMLElement | null>A Vue ref pointing at the scrollable container element.
itemHeightnumberFixed pixel height of each item in the list.
overscannumber2How many extra items to render above + below the viewport.

Return Values

FieldTypeDescription
visibleItemsComputedRef<T[]>The slice of items to render based on scroll position and overscan.
paddingTopComputedRef<number>Height (px) of the spacer above visibleItems to preserve total scroll height.
paddingBottomComputedRef<number>Height (px) of the spacer below visibleItems to preserve total scroll height.
startIndexComputedRef<number>Index of the first item in visibleItems.
endIndexComputedRef<number>One past the index of the last item in visibleItems.
visibleCountComputedRef<number>Number of items that fit into the container’s viewport (excluding overscan).
scrollToIndex(index: number) => voidImperatively scroll so the given item index floats to the top of the container.

Browser support / Vue version

  • Vue: Built and tested with Vue 3.2+. Not compatible with Vue 2.x or earlier.
  • Browsers: Supports all modern “evergreen” browsers—Chrome, Firefox, Edge, Safari, and Opera.
  • Polyfills: No additional polyfills required for standard virtual scrolling functionality; relies on basic DOM APIs and ResizeObserver (included in most modern browsers).
  • SSR: Can be used in server-side rendering builds (Nuxt 3, Vite SSR), but virtualization only activates in the browser (guard against window/document if rendering on the server).
  • Not supported: Internet Explorer and legacy browsers without ES Module support.

License

  • License
    This project is licensed under the MIT License. See the LICENSE file for full details.

FAQs

Package last updated on 15 Jun 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts