# Lists with For

> Render keyed collections with For so list updates move DOM nodes instead of rebuilding them.

Source: [https://askrjs.com/docs/core-concepts/lists-with-for](https://askrjs.com/docs/core-concepts/lists-with-for)

Status: stable. Packages: @askrjs/askr.

**Published packages are authoritative.** Examples may lag behind a published contract. When guidance differs, verify the exports and TypeScript declarations in your installed package, then file an issue.

## Example

Render stable keyed rows and keep row identity separate from array position.

```tsx
import { For } from '@askrjs/askr';

<For each={projects()} by={(project) => project.id}>
  {(project) => <ProjectRow project={project} />}
</For>
```

## Keyed lists

`<For each={items} by={item => item.id}>{(item, index) => ...}</For>` is how Askr renders collections — `each` accepts an array or a function returning one, and the `by` callback supplies a stable string or number key per item. The render callback receives the item plus an `index` accessor function (not a raw number), since an item's position can change as the list reorders.

## Identity and reordering

Keys are what let `For` tell the difference between an item moving and an item being replaced. Internally the runtime tracks commit strategies like `INSERT_ONE`, `REMOVE_ONE`, `SWAP`, and `FULL_KEYED` to patch the DOM with the smallest possible change instead of tearing down and rebuilding rows, but that only works if `by` returns a key that's stable across renders for the same logical item. If you don't need per-item keys, `byIndex: true` opts into index-based identity instead of the `by` callback.

## Empty collections

`For` accepts a `fallback` prop that renders when `each` produces zero items, so you don't need a separate `Show` wrapped around every list to handle the empty case. The fallback is regular JSX — a message, an empty state illustration, whatever — and it's swapped back out automatically the moment the source has items again.

## List performance

Because `For` diffs by key rather than re-rendering every child on every source change, updating one item in a thousand-item list only touches that item's DOM node. The render callback's `index` parameter is a reactive accessor rather than a plain number specifically so that reorders don't force a full re-render of every row just to update its position — only rows that actually read the index value respond when it changes.

## Documentation navigation

[Previous](https://askrjs.com/docs/core-concepts/state-and-derived-values/index.md) | [Next](https://askrjs.com/docs/core-concepts/conditional-rendering/index.md)
