Skip to content

react-hooks-js/incompatible-library flags @tanstack/react-virtual useVirtualizer #950

Description

@NisargIO

Summary

react-hooks-js/incompatible-library flags @tanstack/react-virtual's useVirtualizer hook as an incompatible library API. The current suggested remediation is easy to interpret as "rewrite the virtualizer locally," which can push users away from a mature, battle-tested virtualization package and toward fragile scroll math.

Minimal example

import { useRef } from 'react';
import { useVirtualizer } from '@tanstack/react-virtual';

export function Example({ rows }: { rows: string[] }) {
  const parentRef = useRef<HTMLDivElement>(null);
  const virtualizer = useVirtualizer({
    count: rows.length,
    getScrollElement: () => parentRef.current,
    estimateSize: () => 36,
    overscan: 10,
  });

  return (
    <div ref={parentRef} style={{ height: 300, overflow: 'auto' }}>
      <div style={{ height: virtualizer.getTotalSize(), position: 'relative' }}>
        {virtualizer.getVirtualItems().map((item) => (
          <div key={item.key} style={{ position: 'absolute', transform: `translateY(${item.start}px)` }}>
            {rows[item.index]}
          </div>
        ))}
      </div>
    </div>
  );
}

Why this is tricky

For virtualized lists, replacing the library hook with handwritten fixed-row math is not a neutral compiler cleanup. The library owns subtle behavior around measurement, scroll element changes, dynamic sizing, resize handling, browser edge cases, and imperative scrolling. A diagnostic that points users toward removing it can make code less maintainable and more bug-prone.

Expected behavior

One of these would be preferable:

  • Do not flag useVirtualizer when it is used in the normal render-time pattern recommended by @tanstack/react-virtual.
  • Classify this as an allowlisted/known-library case with guidance to keep the virtualizer behind a focused component boundary if needed.
  • Provide a rule-specific remediation that does not imply reimplementing virtualization locally.

Actual behavior

The hook is reported under react-hooks-js/incompatible-library, with generic guidance to rewrite the flagged code so React Compiler can optimize it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions