---
title: "\U0001F9EA Each | Experimental"
keywords: 'lists, keyed rendering, control flow, loops'
---

import CodeSandbox from '../../../../components/code-sandbox/index.tsx';
import { Note } from '~/components/note/note';

# `Each`

**Stage:** `implementation`

<Note>
  `Each` is experimental and currently a technical preview. Its API and behavior may still change
  as we gather feedback from real-world usage.
</Note>

`Each` is a built-in Qwik component for rendering keyed lists.

It is most useful when list items have a stable identity and you want Qwik to preserve and move
existing rows instead of re-rendering the whole list when the order changes.

To use it, you must add `experimental: ['each']` to your `qwikVite` plugin options:

```ts
// vite.config.ts
import { defineConfig } from 'vite';
import { qwikVite } from '@qwik.dev/core/optimizer';

export default defineConfig(() => {
  return {
    plugins: [
      qwikVite({
        experimental: ['each'],
      }),
    ],
  };
});
```

<CodeSandbox src="/src/routes/demo/component/each/index.tsx" style={{ height: '10em' }}>
```tsx /Each/ /key$/ /item$/
import { Each, component$, useSignal } from '@qwik.dev/core';

type Todo = {
  id: string;
  label: string;
};

export default component$(() => {
  const todos = useSignal<Todo[]>([
    { id: '1', label: 'Write docs' },
    { id: '2', label: 'Review keys' },
    { id: '3', label: 'Ship it' },
  ]);

  return (
    <>
      <button onClick$={() => (todos.value = [...todos.value].reverse())}>
        Reverse order
      </button>

      <ul>
        <Each
          items={todos.value}
          key$={(todo) => todo.id}
          item$={(todo) => <li>{todo.label}</li>}
        />
      </ul>
    </>
  );
});
```
</CodeSandbox>

## Props

`Each` accepts three props:

- `items`: the array to render
- `key$`: returns a stable unique key for each item
- `item$`: returns the JSX for one item

`item$` must return a single JSX node. If you need multiple siblings, wrap them in a container
element or a `Fragment`.

```tsx /Fragment/ /Each/
import { Each, Fragment, component$ } from '@qwik.dev/core';

export default component$(() => {
  return (
    <ul>
      <Each
        items={['a', 'b', 'c']}
        key$={(item) => item}
        item$={(item) => (
          <Fragment>
            <li>Item {item}</li>
          </Fragment>
        )}
      />
    </ul>
  );
});
```

## `Each` vs `items.map()`

If your list items have stable keys, prefer `Each`.

It is the specialized keyed-list primitive in Qwik and is designed to preserve and move existing
rows efficiently.

Use `items.map()` for simple list rendering or when you do not have a stable key:

```tsx
<ul>
  {todos.value.map((todo) => (
    <li key={todo.id}>{todo.label}</li>
  ))}
</ul>
```

Qwik may also be able to optimize some keyed `.map()` patterns into `Each` under the hood in the
future when it can prove the transformation is safe. For now, use `Each` explicitly when you want
its keyed-row preservation behavior.

Prefer `Each` when:

- items have stable ids
- rows are frequently reordered, inserted, or removed
- you want to preserve existing row DOM and component instances

Prefer `map()` when:

- there is no stable key for the item
- you want ordinary JSX list rendering without `Each`'s keyed-row preservation behavior
- the row output should be recomputed from replaced item objects even when the key stays the same

## How keyed updates work

`Each` uses the value from `key$` as the identity of the row.

When keys stay the same, Qwik can move and reuse the existing rows instead of recreating them. This
is why `Each` is a good fit for drag-and-drop lists, sortable tables, and other UIs where items
move around often.

There is an important tradeoff: if you replace an item object but keep the same key, `Each`
preserves the existing row. That means the row template is not re-run just because a new object
with the same key was passed in.

So `Each` is usually the right choice for keyed collections. It has a different update strategy.

If you need the row output to update from replaced item objects, prefer `map()`. If you need
row-local updates with `Each`, model that row state with Qwik reactivity instead of relying on
replacing the whole item object.

## Keys

Choose keys that are stable across renders:

- Good: database ids, slugs, UUIDs
- Avoid: array indexes when the list can be reordered

Using unstable keys defeats the main benefit of `Each` and can produce confusing UI behavior.

## Related

- For general list rendering, see [Rendering](/docs/core/rendering/)
- For the generated API entry, see [API Reference](/api/qwik/#each)
