VirtualList
VirtualList renders a list with a virtualisation seam. Below a threshold it renders every row directly; above it, motif hands off to whatever windowing implementation you registered. The bundle stays dependency-free either way.
What it is
A list component with a swappable rendering strategy. For lists shorter than the threshold
(50 items by default), VirtualList renders each row inside a ScrollView — fast, simple, no
dependency. For longer lists, it delegates to the implementation registered through
registerVirtualListImpl.
The seam exists because virtualisation has a fixed cost. A windowing library is worth its weight
for a 10,000-row list and pure overhead for a 12-row one. Motif ships neither the library nor the
overhead — you wire in react-virtuoso (or any windowing library) once, and only the lists that
need it pay for it.
Install
VirtualList is exported from usemotif. No separate install. The virtualised path needs a
windowing library — install one and register it.
API
VirtualList
stablefunction VirtualList<T>(props: VirtualListProps<T>): JSX.Element
The list items.
Renders one row. Called once per item.
Stable item-id extractor. Falls back to the index when omitted.
Approximate row height. Used by virtualised implementations to size the viewport.
Every ScrollView prop — `h`, `direction`, `hideScrollbar`, and the Box style props.
registerVirtualListImpl
registerVirtualListImpl
stablefunction registerVirtualListImpl(
impl: VirtualListImpl | null,
options?: { threshold?: number },
): voidRegisters the windowing implementation VirtualList delegates to for lists at or above the
threshold. Call it once at app startup. Pass null to clear the registration; pass
options.threshold to change the 50-item cutoff.
Examples
Register a windowing library once at startup:
Use VirtualList anywhere — short lists render directly, long ones virtualise:
Cross-platform notes
On web the fallback path renders rows inside a ScrollView; the virtualised path runs whatever DOM
windowing library you registered. On native, register a native windowing implementation instead —
React Native's FlatList is the usual choice. The VirtualList API is the same on both
platforms; only the registered implementation differs.