npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

react-vscroller

v0.1.0

Published

React component which enables virtual rendering of collections

Readme

React-VScroller

This library is an experiment (and a work in progress). The intent is to prove out the use of IntersectionObserver as a primary mechanism for enabling virtualized rendering of long lists of items.

Primary Goals

  • Avoid scroll event listeners, instead relying on IntersectionObservers to detect relevant scroll changes
  • Support variable sized items
  • Must work well in both a full window and a scrollable container
  • Avoid assumptions about the type of components being rendered - for example, the same components should work with tables, unordered lists, or a collection divs.

Components

VScroller is the primary component, which wraps other sub-components and your content. The only required prop is count, which tells the component how many items are available to render. Other props include:

  • pageSize: The minimum number of items to render at once. (Default 100) If the provided size does not fill the screen, it will be increased until it does.
  • threshold: The buffer in pixels before rendering the next range of records. (Default 300)
  • onRangeChanged: Callback which is executed when a new range of items is rendered, which will receive the Range object as a parameter.
  • fillerStyle: A style object which will be used to style the filler elements above and below the rendered portion. The height of these elements maintains the height of the scrollbar. These elements can become visible briefly during fast scroll transitions, so providing some styling can be useful to give user feedback.

VScroller.Head component can be used to render header content, for example a table header. It contains a sticky property which can be set to indicate that the header is always in the viewport. This doesn't actually change how the content is positioned, but instead tells us when it should be rendered and impacts some calculations.

VScroller.Foot component can be used to render a footer component. This component will render when the bottom of the collection is near visibility.

VScroller.Body component contains the actual content being rendered. This has a render-prop child which is called as items are rendered. The render function takes a single parameter, which is the index of the component to render. The function should return a component that accepts a ref which resolves to the underlying DOM element.

Alternately, for more control the Body component accepts a node and will pass a range prop which contains the inclusive start index and exclusive end index, as well as a done value which tells whether the collection has more items to render. If you use this approach, you should wrap each item in the Item component.

VScroller.Item component wraps an individual item to be rendered. This expects a ref from the child component, which is used to determine the height of the rendered item. (This component is only necessary if you are not using the render prop for the Body component.)

Examples can be found in the Storybook stories included within this repository.

Caveats

  • This library depends on modern browser features like IntersectionObserver and ResizeObserver. This functionality is supported in all major browsers. Polyfills do exist which may enable this library to work in legacy browsers (i.e. I.E.), however this is untested.
  • IntersectionObservers emits notifications asyncronously. This is nice in that it doesn't block the UI thread, but means that there may be a delay between the event occuring and the notification. Because of this, the filler elements may become visible briefly during scrolling - especially when dragging the scrollbar. This can be optimized by experimenting with the pageSize and threshold properties. It's recommended to use the fillerStyle property to give the filler elements a style that will give the user some indication that an update is pending. For example, a checkboard pattern can be seen in the Storybook examples.
  • The threshold property does not work as expected when the content is rendered within an iframe. This can cause the render to for the next range to be delayed, compared to the same scenario outside of an iframe. (This behavior is present in the Storybook examples.)
  • Only supports vertical scrolling, though the concepts could support vertical scrolling as well.

TODO

  • Some real-world usage, testing, and validation (vet defaults, etc)
  • Build more examples, including lists.
  • Optimize support for fixed height items. (This works fine already, but opimizations can be made for this scenario.)