Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/danielitoCode/compose_svelted/llms.txt

Use this file to discover all available pages before exploring further.

LazyColumn and LazyRow are the virtualized list containers in Compose Svelted. Instead of rendering every item in the DOM at once, they calculate which items are currently visible inside their scroll viewport and render only that window — plus a small overscan buffer of 3 items on each edge to prevent blank flashes during fast scrolling. Both components scroll vertically (overflow-y: auto). They are ideal for feeds, search results, message histories, or any list that could grow to hundreds of items. For short, bounded lists where all items should always be in the DOM, a plain Column with Modifier.verticalScroll(true) is simpler and has no overhead.

How virtualization works

On mount, each component measures the height of the first rendered item to establish a uniform estimated item height (fallback: 56 px, a comfortable Material baseline). It then maintains three reactive values:
  • startIndex — first item to render based on current scroll position and the estimated height
  • endIndex — last item to render, accounting for the visible viewport height and overscan
  • visibleItems — the slice of items between those two indices
A full-height spacer div preserves the correct scrollbar size, and the visible window is absolutely positioned at startIndex * estimatedItemHeight pixels from the top. This means the scroll experience feels native even for very large lists.
Item height estimation is uniform — all items are assumed to be the same height as the first rendered item. If your items vary significantly in height, the scrollbar thumb may jump slightly as the user scrolls. Variable-height virtualization is not currently supported.

Props

Both LazyColumn and LazyRow share the same prop surface:
PropTypeDefaultDescription
itemsany[][]The full array of data to render. The component virtualizes over this array.
modifierModifierModifier.empty()Applied to the scroll container. Use this to constrain height, since an unconstrained container cannot scroll.
horizontalAlignmentHorizontalAlignmentAlignment.StartCross-axis alignment of items within the visible window (align-items).
verticalArrangementArrangementValueArrangement.StartControls the gap between rendered items. Only Arrangement.spacedBy(n) produces a gap; all other values produce 0 px.

Slot

Both components expose a single default slot with an item binding that carries the current element from your items array:
<LazyColumn {items} let:item>
  <!-- item is the current element -->
</LazyColumn>

LazyColumn

LazyColumn renders its list along the vertical axis with overflow-y: auto. The container must have a bounded height — use Modifier.fillMaxSize(), Modifier.height(n), or Modifier.fillMaxHeight().
<script>
  import { LazyColumn, Row, Text, Surface, Modifier, Alignment, Arrangement } from '@danielito1996/compose-svelted';

  const messages = Array.from({ length: 500 }, (_, i) => ({
    id: i,
    author: i % 2 === 0 ? 'Alice' : 'Bob',
    body: `Message number ${i + 1}`,
  }));
</script>

<LazyColumn
  items={messages}
  modifier={Modifier.fillMaxSize()}
  horizontalAlignment={Alignment.Start}
  verticalArrangement={Arrangement.spacedBy(8)}
  let:item
>
  <Surface modifier={Modifier.fillMaxWidth().padding(12)}>
    <Row horizontalArrangement={Arrangement.spacedBy(8)} verticalAlignment={Alignment.CenterVertically}>
      <Text textStyle="labelLarge">{item.author}</Text>
      <Text>{item.body}</Text>
    </Row>
  </Surface>
</LazyColumn>

LazyRow

LazyRow shares the same implementation and props as LazyColumn. It also scrolls vertically (overflow-y: auto), making it suitable for vertically-scrolling card stacks and feed variations where a distinct component name communicates intent. The container must have a bounded height.
<script>
  import { LazyRow, Surface, Text, Modifier, Alignment, Arrangement } from '@danielito1996/compose-svelted';

  const products = Array.from({ length: 200 }, (_, i) => ({
    id: i,
    name: `Product ${i + 1}`,
    price: `$${(9.99 + i).toFixed(2)}`,
  }));
</script>

<LazyRow
  items={products}
  modifier={Modifier.fillMaxSize()}
  horizontalAlignment={Alignment.Start}
  verticalArrangement={Arrangement.spacedBy(12)}
  let:item
>
  <Surface modifier={Modifier.fillMaxWidth().padding(16)}>
    <Text textStyle="titleMedium">{item.name}</Text>
    <Text>{item.price}</Text>
  </Surface>
</LazyRow>

LazyColumn vs Column — when to use each

ConcernColumn + verticalScrollLazyColumn / LazyRow
List lengthTens of itemsHundreds or thousands
All items in DOM✅ Yes❌ No — only visible window
CSS animations on itemsWorks naturallyMay flicker on fast scroll
Variable item heightsFully supportedUniform height assumed
SetupNo extra props neededRequires items array and slot binding
Give LazyColumn and LazyRow an explicit, bounded size via modifier. A container with no height constraint cannot scroll and will render the full items array, defeating the purpose of virtualization.
<!-- ✅ Correct — bounded by the parent scaffold content area -->
<LazyColumn items={rows} modifier={Modifier.fillMaxSize()} let:item>
  ...
</LazyColumn>

<!-- ❌ Avoid — no height constraint, all items render at once -->
<LazyColumn items={rows} let:item>
  ...
</LazyColumn>

Build docs developers (and LLMs) love