Skip to content
dhiltPublic

Repository files navigation

build status npm version

VScroll

A framework-independent virtual scrolling engine for JavaScript and TypeScript.

Overview

Virtual scrolling is a technique for displaying large lists efficiently. Instead of rendering every item at once, it keeps a small set of items in the DOM — those in and around the visible area — and updates that set as the user scrolls. This reduces DOM size and rendering work while preserving a familiar scrolling experience.

VScroll provides a framework-independent core engine for virtual scrolling. An application can use it directly or through a platform-specific wrapper called a consumer. The diagram shows how the engine reaches the end user when a consumer is used.

VScroll core distributed through consumers and applications to the end user

The minimal browser demo demonstrates direct use of VScroll without a separate consumer.

Existing consumers and integration examples include:

Installation

CDN

Load the library in a browser and access its exports through VScroll:

<script src="https://cdn.jsdelivr.net/npm/vscroll"></script>
<script>
  new VScroll.Workflow(...);
</script>

For reproducible deployments, pin the CDN URL to a package version.

NPM

npm install vscroll

Import the library in the application's build:

import * as VScroll from 'vscroll';

new VScroll.Workflow(...);

Usage

A vscroll consumer is responsible for the integration: supplying data when requested by the engine and rendering the current buffer in the DOM. The engine manages scrolling, determines which items are needed, and updates the buffer; the consumer defines how data is retrieved and displayed. This integration is configured when creating Workflow, the main entry point to the engine.

Workflow

The Workflow class, exported by vscroll, is where the integration is configured. Instantiating it starts the engine. See the Workflow reference for the requirements behind its constructor parameters.

const workflow = new VScroll.Workflow({ consumer, element, datasource, run, Routines });
Parameter Purpose
consumer Static integration metadata (name and version), used in diagnostics.
element The mounted DOM element containing the rendered list, not the scrollable viewport.
datasource The object that supplies data and scrolling settings, described below. See also Datasource.
run(items) The callback that keeps the rendered list in sync with the complete current buffer, including offscreen items. See Rendering.
Routines Optional subclass of VScroll.Routines for customizing DOM operations and render scheduling. See Custom Routines.

Datasource

Every Workflow requires a datasource object to supply items on request and, optionally, configure scrolling. Its data and configuration fields are { get, settings, devSettings }. See the Datasource reference for the full contract, supported signatures, and implementation examples.

  • get is the required data retrieval function, called with a starting index and item count. It can be synchronous or asynchronous. A minimal callback example providing a synchronous, infinite data stream:

    const get = (index, count, callback) =>
      callback(Array.from({ length: count }, (_, i) => `Item ${index + i}`));
  • settings is an optional object for configuring scrolling. The table below summarizes its options and defaults. See Configuration for types, constraints and examples.

    Setting Default Purpose
    startIndex 1 Initial item index, clamped to the configured bounds.
    minIndex -Infinity Inclusive lower dataset index bound.
    maxIndex Infinity Inclusive upper dataset index bound.
    padding 0.5 Extra buffered area on each side, in viewport sizes.
    bufferSize 5 Minimum fetch batch target, not a limit on buffered items.
    itemSize NaN Initial item-size estimate in pixels; measured automatically when omitted.
    sizeStrategy 'average' Estimate unknown item sizes using 'average', 'frequent' or 'constant'.
    viewportElement null Custom viewport element or element factory; defaults to the content element's parent. Experimental.
    windowViewport false Use the browser window as the viewport.
    horizontal false Scroll horizontally instead of vertically.
    inverse false Align short content to the bottom or right without reversing item order. Experimental.
    infinite false Keep loaded items instead of clipping them automatically.
    onBeforeClip null Receive clipped items just before they leave the buffer. Experimental.
  • devSettings is an optional object for logging, timing, caching and scroll behavior. See Development settings for its options and defaults.

Adapter API

The Adapter API extends the scrolling engine with reactive state observation and runtime control. It provides access to loading state, visible items and dataset boundaries, supports adding, removing and updating items or reloading data, and enables synchronization of application actions with scroller activity. These capabilities support interactive interfaces such as chats, live feeds and editable lists, where content evolves in response to incoming data and user actions.

The Adapter API is available when a datasource is created through the makeDatasource factory exported by vscroll.

const Datasource = VScroll.makeDatasource();
const datasource = new Datasource({ get, settings });
const adapter = datasource.adapter;

// Reload data when the refresh button is clicked.
refreshButton.addEventListener('click', () => adapter.reload());

// Log loading state changes.
adapter.isLoading$.on(isLoading => console.log('Loading:', isLoading));

The Adapter is created when the datasource is instantiated. Its reactive properties can be observed before constructing Workflow, but method calls have no effect until Workflow finishes initializing. See Calling Adapter methods.

makeDatasource also accepts an optional configuration factory for customizing the Adapter's reactive properties. See Custom Adapter reactivity.

The tables below provide a brief overview of the Adapter's properties and methods. See Adapter properties and Adapter methods for details, and the ngx-ui-scroll Adapter demos for interactive examples.

Properties

Properties are read-only. Each $ counterpart provides reactive updates.

Property Purpose
init, init$ Whether the Adapter is initialized.
isLoading, isLoading$ Whether a workflow cycle is running, including fetching and rendering.
loopPending, loopPending$ Whether an inner workflow loop is running.
paused, paused$ Whether workflow processing is paused.
bufferInfo Buffer, cache and dataset index bounds, plus the estimated item size.
itemsCount Number of rendered buffer items, including offscreen items.
firstVisible, firstVisible$ First item intersecting the viewport, including a partially visible item.
lastVisible, lastVisible$ Last item intersecting the viewport, including a partially visible item.
bof, bof$ Whether the buffer has reached the dataset's beginning.
eof, eof$ Whether the buffer has reached the dataset's end.
packageInfo Core and consumer package names and versions.

Methods

Method Purpose
relax Wait until the scroller is idle.
reload Reload data at an optional starting index, keeping the current configuration.
reset Restart the scroller with optional datasource and settings changes.
pause, resume Suspend or resume workflow processing.
append, prepend Add items after or before the known range.
insert Insert items before or after a target item.
remove Remove selected items by predicate or indexes.
replace Replace matching buffered items with a new set of items.
update Keep, remove or replace buffered items using a callback.
check Re-measure rendered items after their sizes change.
clip Trim offscreen buffer items beyond the configured padding.
fix Directly adjust scroll position, index bounds or items. Experimental.
showLog Print collected debug logs.

Documentation

See the documentation index for a guided path through the reference pages below.

Thanks


2026 © Denis Hilt · MIT license

Releases

Sponsor this project

Packages

Used by

Contributors

Languages