Virtualise large data lists easily with react-window

Find out how to effectively virtualise large lists of data using react-window and improve your users' experience.
•
Updated on August 14, 2026
•
10 min read
Believemy logo

Effectively managing large data lists can quickly become very complicated in a React application: the more data there is to display, the more performance will be impacted.

When thousands of items need to be displayed (such as a list of registered users or a list of articles): it’s catastrophic for the user experience, with a browser trying to keep up and ending up crashing one out of three times. 🥲

Fortunately, there is a solution: react-window ✨

This is a React library very handy for managing large amounts of data. We’re talking about virtualization.

Good to know

When we talk about virtualizing something, it means that we will only display a small portion of the elements visible in the viewport (the browser window).

Virtualization has several advantages:

  1. Reduce page loading because only the data directly visible on the screen by the user is loaded;
  2. Improve fluidity because fewer data elements are present in the DOM, so the browser has less work to do to scroll through a page;
  3. Boost the user experience because the user ends up with a page that loads quickly.

 

Why Use react-window?

The advantages of react-window are numerous for React developers who need to manage large amounts of data in their projects:

  1. Extremely lightweight and very fast - Compared to other libraries like react-virtualized, with which it is often compared (we’ll discuss it just after), react-window is much lighter;
  2. Improved performance - Enabling virtualization, as we saw, greatly improves the page loading performance (and we love that!) ;
  3. Supports different types of lists - In the form of grids, horizontal or vertical lists, everything is supported by react-window without any issues.

 

Installing react-window

To start using react-window, you need a React-based project (no joke 🙃).

Once that's done, simply install the library with npm:

CONSOLE
npm install react-window

Or if you prefer yarn:

CONSOLE
yarn add react-window

 

Create a List with react-window

Lists are the most commonly used formats for displaying data. They allow adding all elements one by one below each other.

Create a Fixed-Size List with FixedSizeList

The main component of react-window is the FixedSizeList component. It allows displaying a list of fixed-size elements.

Let’s look at a small example:

JSX
import React from 'react';
import { FixedSizeList as List } from 'react-window';

const items = Array(5000).fill().map((_, index) => `Item ${index + 1}`);

function Row({ index, style }) {
  return (
    <div style={style}>
      {items[index]}
    </div>
  );
}

export default function App() {
  return (
    <List
      height={500}
      itemCount={items.length}
      itemSize={40}
      width={500}
    >
      {Row}
    </List>
  );
}

In this example, we use a 5000-element list (Array(5000)) which we fill to provide a generic list that we can work with.

CONSOLE
["Item 1","Item 2","Item 3","Item 4","Item 5","Item 6","Item 7","Item 8","Item 9","Item 10","Item 11","Item 12","Item 13", ...]

We then use the FixedSizeList component renamed to List according to best practices:

  • height - defines the visible height of the list
  • itemCount - the total number of items in our complete list
  • itemSize - the height of each item
  • width - also defines the visible width of the list

Thanks to the FixedSizeList component, we now have a list of 5000 elements that displays in the blink of an eye!

Good to know

If you prefer to display a horizontal list that allows scrolling like a slider (like Netflix), you can do so! Just add the layout property:

 

Create a Variable-Size List with VariableSizeList

Often, our items do not have a fixed size: therefore, we cannot use FixedSizeList.

Fortunately, another option offered by react-window is to use the VariableSizeList component (the name says it all 😋).

This component allows you to manage variable sizes. Here is an example:

JSX
import React from 'react';
import { VariableSizeList as List } from 'react-window';

const items = Array(5000).fill().map((_, index) => `Item ${index + 1}`);

function getItemSize(index) {
  return 30 + (index % 10) * 10; // Example of variable size
}

function Row({ index, style }) {
  return (
    <div style={style}>
      {items[index]}
    </div>
  );
}

export default function App() {
  return (
    <List
      height={500}
      itemCount={items.length}
      itemSize={getItemSize}
      width={500}
    >
      {Row}
    </List>
  );
}

In this example, all the items in our list have a different size calculated using the getItemSize function.

Good to know

As with FixedSizeList, you can request a horizontal layout by specifying layout="horizontal" 🙂

 

Create Grids with react-window

In addition to lists, react-window allows managing data grids with the FixedSizeGrid and VariableSizeGrid components. Presented in table form, these components are very useful for displaying data with rows and columns.

Create a Fixed-Size Grid with FixedSizeGrid

Here’s how to create a fixed-size grid with react-window:

JSX
import React from 'react';
import { FixedSizeGrid as Grid } from 'react-window';

function Cell({ columnIndex, rowIndex, style }) {
  return (
    <div style={style}>
      {`Row ${rowIndex}, Column ${columnIndex}`}
    </div>
  );
}

export default function App() {
  return (
    <Grid
      columnCount={100}
      columnWidth={100}
      height={500}
      rowCount={100}
      rowHeight={35}
      width={500}
    >
      {Cell}
    </Grid>
  );
}

In this example, a grid of 100 cells wide by 100 cells tall is displayed! This could cause some slowdowns for the browser, but not with react-window which only loads the cells that are visible on the screen.

To go into detail:

  • columnCount - this property specifies the total number of columns in the grid (here 100 columns);
  • columnWidth - specifies the width of each column in pixels (100 pixels in the example);
  • height - indicates the total height of the grid in pixels;
  • rowCount - specifies the number of rows in the grid;
  • rowHeight - defines the height of each row in pixels;
  • width - indicates the total width of the grid in pixels.
Good to know

Thanks to these parameters, the grid will display a subset of the elements.

Only the 5 columns (100 pixels each) out of the 100 total columns will be visible at any given time. When the user scrolls horizontally, new columns will be rendered in the DOM.

Similarly, only 14 rows (35 pixels each) out of the 100 rows will be visible at any given time in the window (since it is 500 pixels in height).

With a real example, here’s what we could have to display our registered users on our website:

JSX
import React from 'react';
import { FixedSizeGrid as Grid } from 'react-window';

const users = [
  { userId: 1, firstName: 'John', lastName: 'Doe' },
  { userId: 2, firstName: 'Jane', lastName: 'Smith' },
  { userId: 3, firstName: 'Paul', lastName: 'Johnson' },
  // etc
];

// Number of columns (id, first name, last name)
const columnCount = 3;

// Width of each column
const columnWidth = 150;

// Height of each row
const rowHeight = 40;

// Total visible grid width (based on 3 columns)
const gridWidth = columnCount * columnWidth;

// Total visible grid height (example of 6 visible rows)
const gridHeight = 6 * rowHeight;

function Cell({ columnIndex, rowIndex, style }) {
  const user = users[rowIndex];
  
  // Determines what content to display based on the column index
  let content;
  switch (columnIndex) {
    case 0:
      content = user.id;
      break;
    case 1:
      content = user.firstName;
      break;
    case 2:
      content = user.lastName;
      break;
    default:
      content = '';
  }

  return (
    <div style={style}>
      {content}
    </div>
  );
}

export default function App() {
  return (
    <Grid
      columnCount={columnCount}
      columnWidth={columnWidth}
      height={gridHeight}
      rowCount={users.length}
      rowHeight={rowHeight}
      width={gridWidth}
    >
      {Cell}
    </Grid>
  );
}

In this example, all the lines are explained so that you can follow along. What you need to remember is that it is sufficient to use the item index to correctly place the associated information (here, about a user). 😬

 

Create a Variable-Size Grid with VariableSizeGrid

To work with variable-sized items in a grid, you can use the VariableSizeGrid component provided by react-window.

In this example, we will use columns to display id, firstName, and lastName (I deliberately used French to make this topic a bit more complex yet accessible to as many as possible 😋), but each column and each row will have a different size, which is managed by VariableSizeGrid.

JSX
import React from 'react';
import { VariableSizeGrid as Grid } from 'react-window';

// Example user data
const users = [
  { userId: 1, firstName: 'John', lastName: 'Doe' },
  { userId: 2, firstName: 'Jane', lastName: 'Smith' },
  { userId: 3, firstName: 'Paul', lastName: 'Johnson' },
  // etc
];

// Function to return the width of each column dynamically
const getColumnWidth = (index) => {
  switch (index) {
    case 0: // id
      return 100;
    case 1: // first name
      return 150;
    case 2: // last name
      return 200;
    default:
      return 100;
  }
};

// Function to return the height of each row
const getRowHeight = (index) => {
  return 40 + (index % 3) * 10; // Here with a variable height
};

function Cell({ columnIndex, rowIndex, style }) {
  const user = users[rowIndex];
  
  // Determines what content to display based on the column index
  let content;
  switch (columnIndex) {
    case 0:
      content = user.id;
      break;
    case 1:
      content = user.firstName;
      break;
    case 2:
      content = user.lastName;
      break;
    default:
      content = '';
  }

  return (
    <div style={style}>
      {content}
    </div>
  );
}

export default function App() {
  return (
    <Grid
      columnCount={3} // Three columns: id, first name, last name
      columnWidth={getColumnWidth} // Column widths defined dynamically
      height={400} // Visible grid height
      rowCount={users.length} // Number of rows = number of users
      rowHeight={getRowHeight} // Row heights defined dynamically
      width={500} // Visible grid width
    >
      {Cell}
    </Grid>
  );
}

In this example, all our users have a different height calculated by getRowHeight and a different cell width calculated based on the information to display: id, firstName, or lastName.

 

Conclusion

React-window is truly a powerful and lightweight solution for effortlessly managing large data lists!

As we’ve seen, the library can just as well handle displaying lists as it can handle grids.

Although mastering it takes some time, it’s a real must-have for all projects that aim to improve the user experience.

 

FAQ

We’ve condensed for you the most frequently asked questions our learners ask us when they talk about react-window! 😬

Question

What is the difference between react-window and react-virtualized?

They are often compared! react-window is lighter and more performant for most use cases. react-virtualized offers more features, but is much more complex to set up and is also heavier: which goes against what we’re looking for.

Created by the same developer, react-virtualized was the first one; react-window was created later to balance the complexity of react-virtualized.

So if you want a little advice: use react-window instead of react-virtualized. 😉

 

Question

What are the advantages of virtualization?

Virtualization allows you to render only the elements visible in your DOM, which improves performance, especially when rendering long lists.

 

Question

What is the maximum size allowed for using react-window?

Actually, there is none! You can use react-window for as much data as you want.

 

Question

Is it possible to fetch data as the user scrolls through the list?

Yes! With a library developed by the developer of react-window: react-window-infinite-loader.

 

Question

I want to continue learning React, which training should I choose? 🤔

Ours, of course! 🙄

Category: Developers

Share this article

Want to help us? Share this article on your networks or even better: on your site, in an article or in your newsletter.

Believemy logo
Comments (0)

You need to be logged in to comment on this article: log in or sign up.

Read next

What's new in React 19

React 19 has just been announced by the Meta team. Powerful new features have been introduced almost two years after the release of React 18.3. Let's find out what's new with React 19.

December 5, 2024

Why you should learn React in 2025: all the benefits!

Explore why React remains a must-have choice in 2025 for developers. Discover its advantages, the evolution of its features and why the market continues to prefer it.

December 6, 2024

Respecting SOLID principles with React

The SOLID principles are a set of five fundamental programming concepts. They are mostly applied in OOP (Object-Oriented Programming). They can also be applied elsewhere. They are indispensable in software architecture. To present these principles, I've chosen to use Javascript rather than Typescript, so as not to weigh down the examples. We're going to apply these principles to a simple "Todo List".

December 11, 2024

Understanding the Window object with JavaScript

Find out all about the Window object with JavaScript: URL manipulation with window.location, history with window.history, DOM with window.document, browser with window.navigator, and screen with window.screen.

December 9, 2024

Code faster with React using these techniques

Learn how to code faster with React thanks to simple but effective techniques used by experienced developers.

December 9, 2024

Creating a markdown previewer with React

Creating a real markdown previewer with React, and above all, doing it correctly, requires real concentration! Fortunately, with a little help anyone can do it. Here are a few tips for creating your own markdown previewer!

December 9, 2024

Understanding .env files with ReactJS

Find out how to really use the .env file with React or NextJS so you never make a mistake again.

December 9, 2024

All about the new React Hook: useOptimistic

Discover useOptimistic, the React hook that makes your interfaces more responsive with instant updates. Streamline your user experience and simplify error handling. Slug: all about the new-hook-react-useoptimistic

December 9, 2024

Become the solopreneur you dream of being.

First project, career change, business launch: access our courses, practice on real-world cases, and move forward with clear guidance.