> Markdown version of [Virtual List](https://vaadin.com/docs/latest/components/virtual-list). Section index: [llms.txt](https://vaadin.com/docs/latest/components/llms.txt)

# Virtual List

Virtual List allows you to render a long list of items inside a scrollable container without sacrificing performance. Each item is rendered on the fly as the user scrolls the list.

To use this component, you need to assign it a set of data items and a *renderer* that’s used to render each individual data item. The height of an item is determined by its content and can change dynamically.

**Lit** — `virtual-list-basic.ts`

```html
<vaadin-virtual-list
  .items="${this.people}"
  ${virtualListRenderer(this.personCardRenderer, [])}
></vaadin-virtual-list>
```

**Lit** — `Person.ts`

```typescript
import type Address_1 from "./Address.js";
interface Person {
    firstName: string;
    lastName: string;
    email: string;
    birthday: string;
    id: number;
    subscriber: boolean;
    membership: string;
    pictureUrl: string;
    profession: string;
    address: Address_1;
    managerId?: number;
    manager: boolean;
    status: string;
    fullName?: string;
}
export default Person;
```

**Flow** — `VirtualListBasic.java`

```java
VirtualList<Person> list = new VirtualList<>();
list.setItems(people);
list.setRenderer(personCardRenderer);
add(list);
```

**Flow** — `Person.java`

```java
public class Person {

    @Nonnull
    private String firstName;

    @Nonnull
    private String lastName;

    @Nonnull
    private String email;

    @Nonnull
    private Date birthday;

    @Nonnull
    private Integer id;

    @Nonnull
    private Boolean subscriber;

    @Nonnull
    private String membership;

    @Nonnull
    private String pictureUrl;

    @Nonnull
    private String profession;

    @Nonnull
    private Address address;

    private Integer managerId;

    @Nonnull
    private Boolean manager;

    @Nonnull
    private String status;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getFullName() {
        return firstName + " " + lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public boolean isSubscriber() {
        return subscriber;
    }

    public void setSubscriber(boolean subscriber) {
        this.subscriber = subscriber;
    }

    public String getMembership() {
        return membership;
    }

    public void setMembership(String membership) {
        this.membership = membership;
    }

    public String getPictureUrl() {
        return pictureUrl;
    }

    public void setPictureUrl(String pictureUrl) {
        this.pictureUrl = pictureUrl;
    }

    public String getProfession() {
        return profession;
    }

    public void setProfession(String profession) {
        this.profession = profession;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    @Override
    public int hashCode() {
        return id;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (!(obj instanceof Person)) {
            return false;
        }
        Person other = (Person) obj;
        return id == other.id;
    }

    public Integer getManagerId() {
        return managerId;
    }

    public void setManagerId(Integer managerId) {
        this.managerId = managerId;
    }

    public boolean isManager() {
        return manager;
    }

    public void setManager(boolean manager) {
        this.manager = manager;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }
}
```

**React** — `virtual-list-basic.tsx`

```tsx
function Example() {
  const people = useSignal<Person[]>([]);
  const expandedPeople = useSignal<Person[]>([]);

  useEffect(() => {
    getPeople().then(({ people: items }) => {
      people.value = items;
    });
  }, []);

  const personCardRenderer = useCallback(
    ({ item: person }: { item: Person }) => (
      <HorizontalLayout theme="spacing margin">
        <Avatar
          img={person.pictureUrl}
          name={`${person.firstName} ${person.lastName}`}
          style={avatarStyle}
        />

        <VerticalLayout>
          <b>
            {person.firstName} {person.lastName}
          </b>
          <span>{person.profession}</span>

          <Details
            summary="Contact information"
            opened={expandedPeople.value.includes(person)}
            onClick={({ currentTarget: details }) => {
              if (details.opened) {
                expandedPeople.value = [...expandedPeople.value, person];
              } else {
                expandedPeople.value = expandedPeople.value.filter((p) => p !== person);
              }
            }}
          >
            <VerticalLayout>
              <span>{person.email}</span>
              <span>{person.address.phone}</span>
            </VerticalLayout>
          </Details>
        </VerticalLayout>
      </HorizontalLayout>
    ),
    []
  );

  return <VirtualList items={people.value} renderer={personCardRenderer} />;
}
```

**React** — `Person.ts`

```typescript
import type Address_1 from "./Address.js";
interface Person {
    firstName: string;
    lastName: string;
    email: string;
    birthday: string;
    id: number;
    subscriber: boolean;
    membership: string;
    pictureUrl: string;
    profession: string;
    address: Address_1;
    managerId?: number;
    manager: boolean;
    status: string;
    fullName?: string;
}
export default Person;
```

`F93C6D28-18D6-4403-B3B6-0D13F8705BED`
