{"id":11907,"library":"react-virtuoso","title":"React Virtuoso","description":"React Virtuoso is a high-performance virtual scroll component library designed for efficiently rendering large lists, grids, and tables in React applications. It achieves this by virtualizing items, meaning only the visible elements are rendered, significantly optimizing performance and memory usage, especially for thousands of items. The current stable version is 4.18.5, and the project maintains an active release cadence with frequent patch and minor updates. Key differentiators include automatic handling of variable and dynamic item sizes without requiring manual measurement, responsive container sizing that adapts seamlessly to parent and viewport changes (including complex flexbox layouts), and robust support for bi-directional endless scrolling through `startReached` and `endReached` callbacks. The library also offers specialized components like `GroupedVirtuoso` for lists with sticky headers, `VirtuosoGrid` for responsive grid layouts, and `TableVirtuoso` for virtualized tables, providing extensive customization options and integration capabilities with popular UI libraries like shadcn/ui, MUI, and Mantine.","status":"active","version":"4.18.5","language":"javascript","source_language":"en","source_url":"https://github.com/petyosi/react-virtuoso","tags":["javascript","chat","endless","feed","grid","infinite","list","load more","react","typescript"],"install":[{"cmd":"npm install react-virtuoso","lang":"bash","label":"npm"},{"cmd":"yarn add react-virtuoso","lang":"bash","label":"yarn"},{"cmd":"pnpm add react-virtuoso","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Peer dependency required for all React components.","package":"react","optional":false},{"reason":"Peer dependency required for rendering React components to the DOM.","package":"react-dom","optional":false}],"imports":[{"note":"React Virtuoso primarily uses named exports. CommonJS `require` syntax is not recommended in modern React/ESM projects, especially for libraries built with ESM in mind.","wrong":"const Virtuoso = require('react-virtuoso').Virtuoso;","symbol":"Virtuoso","correct":"import { Virtuoso } from 'react-virtuoso';"},{"note":"All major components are named exports from the main `react-virtuoso` package. There are no separate entry points for `grouped` or `table` components.","wrong":"import GroupedVirtuoso from 'react-virtuoso/grouped';","symbol":"GroupedVirtuoso","correct":"import { GroupedVirtuoso } from 'react-virtuoso';"},{"note":"For TypeScript users, type imports like `import type { VirtuosoHandle } from 'react-virtuoso';` are available for component instances.","wrong":"import { TableVirtuoso } from 'react-virtuoso/table';","symbol":"TableVirtuoso","correct":"import { TableVirtuoso } from 'react-virtuoso';"}],"quickstart":{"code":"import { Virtuoso } from 'react-virtuoso';\nimport React from 'react';\n\nconst generateItems = (count: number) =>\n  Array.from({ length: count }, (_, i) => ({\n    id: i,\n    text: `Item ${i + 1}`,\n    height: Math.random() * 50 + 50 // Simulate variable heights\n  }));\n\nexport default function MyVirtualizedList() {\n  const items = React.useMemo(() => generateItems(5000), []);\n\n  return (\n    <div style={{ height: '400px', border: '1px solid #ccc', margin: '20px' }}>\n      <h2 style={{ padding: '10px', margin: 0, background: '#f0f0f0' }}>Large Virtual List Example</h2>\n      <Virtuoso\n        style={{ height: 'calc(100% - 60px)' }} // Adjust for title height\n        totalCount={items.length}\n        itemContent={(index) => (\n          <div\n            style={{\n              padding: '15px 10px',\n              borderBottom: '1px solid #eee',\n              background: index % 2 === 0 ? '#fafafa' : 'white',\n              height: items[index].height // Use pre-calculated variable height\n            }}\n          >\n            <strong>{items[index].text}</strong>: This is content for item {index}.\n            It demonstrates variable height functionality.\n          </div>\n        )}\n        // Optional: Implement infinite scroll\n        // endReached={() => {\n        //   console.log('End of list reached, fetching more data...');\n        //   // In a real app, you would fetch more items here\n        // }}\n        // overscan={200} // Render 200px before/after viewport for smoother scroll\n      />\n    </div>\n  );\n}","lang":"typescript","description":"This quickstart demonstrates a basic `Virtuoso` component rendering a list of 5000 items with simulated variable heights within a fixed-height container, showcasing its core virtualization capabilities."},"warnings":[{"fix":"Upgrade `react-virtuoso` to version `4.18.5` or higher to ensure proper `useSyncExternalStore` detection and avoid tearing issues with React 18+ and 19+ concurrent rendering.","message":"Older versions of `react-virtuoso` (prior to 4.18.5) had an issue with `useSyncExternalStore` detection for React 19+, falling back to a legacy subscription path which could cause 'tearing issues' in concurrent rendering scenarios. This was due to a version check that incorrectly excluded React 19.","severity":"breaking","affected_versions":"<4.18.5"},{"fix":"Ensure the `Virtuoso` component or its direct parent has a CSS `height` (e.g., `height: '100%'`, `height: '500px'`) or `max-height` to establish a scrollable viewport. Consider using a flexbox layout for responsive sizing.","message":"Virtualized lists require their container to have a defined height. If the `Virtuoso` component or its parent does not have an explicit `height` or `max-height` CSS property, the list will not render, or it may render with a `zero-sized element` error.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Instead of `margin`, use `padding` on the item content or its internal elements to create spacing, or use CSS `gap` on the parent container if applicable. If margins are unavoidable, ensure they do not protrude outside the item container.","message":"Applying CSS `margin` to individual list items or their direct children can lead to incorrect scroll height calculations, preventing users from scrolling to the end of the list or causing scroll jumping. Virtuoso uses `ResizeObserver` which reports `contentRect` and does not include margins.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Use `React.memo` for the components rendered inside `itemContent` to prevent unnecessary re-renders. Implement simplified placeholders (skeletons) for heavy content while scrolling by hooking into the `isScrolling` callback. Optimize the rendering logic within `itemContent` to be as lightweight as possible.","message":"Complex or slow-rendering content within `itemContent` can cause performance issues (jank) during scrolling, especially with many items or dynamic content like images.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Apply a `style={{ height: '...' }}` or `style={{ maxHeight: '...' }}` to the `Virtuoso` component or its parent element. For example, `style={{ height: '100%' }}`.","cause":"The Virtuoso component or its parent container does not have an explicit CSS height property defined.","error":"Error: Virtuoso container has no height."},{"fix":"Ensure that items rendered by `itemContent` are not empty and have a measurable size. Check for any CSS that might inadvertently collapse the item's dimensions. Enable debug logging (`logLevel={LogLevel.DEBUG}`) to inspect item sizes.","cause":"This error typically indicates that an item rendered by Virtuoso has zero height or width, which is not supported, or there's an exotic integration bug.","error":"Error: zero-sized element, this should not happen"},{"fix":"Update your build tools (Webpack, Babel) to support ES Modules. Ensure your Webpack configuration includes a rule to process `.mjs` files if present, or upgrade to Webpack 5+.","cause":"This error usually occurs in older build environments (e.g., Webpack 4) when importing modern JavaScript modules (like ES Modules in `.mjs` files) without proper configuration.","error":"Module parse failed: You may need an appropriate loader to handle this file type."},{"fix":"Ensure that the `itemContent` prop is always passed a function that accepts `index` (and `groupIndex` for `GroupedVirtuoso`) and returns a React element. For example: `itemContent={(index) => <div>Item {index}</div>}`.","cause":"The `itemContent` prop, which is a render prop, was not provided as a function.","error":"TypeError: itemContent is not a function"}],"ecosystem":"npm"}