How to Repeat a Svelte Foreach Block a Specific Number of Times

To repeat a Svelte {#each} block a specific number of times, supply an array with length equal to your desired count, typically generated using [...Array(n).keys()], Array(n), or Array.from().

The Svelte compiler transforms {#each} blocks into optimized runtime code that iterates over any JavaScript iterable. When you need to repeat a Svelte foreach block a specific number of times rather than iterating over existing data, you can dynamically generate an index array directly in your component template or script, as implemented in the sveltejs/svelte repository.

The Range Helper Pattern

The most idiomatic approach defines a reusable helper that returns an array of indices. In packages/svelte/src/compiler/print/index.js, the compiler treats {#each} expressions as EachBlock nodes that accept any valid iterable, including generated arrays.

Define a range function in your component script and pass its result to the {#each} block:

<script>
	export let count = 5;
	
	// Returns [0, 1, ..., count-1]
	const range = n => [...Array(n).keys()];
</script>

{#each range(count) as i}
	<p>Iteration {i + 1}</p>
{/each}

This pattern works because Array(n) creates an empty array of length n, and spreading with .keys() materializes it into a concrete array of indices that satisfies the EachBlock's iterable requirement.

Inline One-Liner Alternatives

For simpler components, you can generate the index array directly inside the template expression without a helper function.

Using Array with Index

Pass Array(count) as the iterable and capture the index parameter:

{#each Array(count) as _, i}
	<p>Item {i + 1}</p>
{/each}

Using Array.from

For explicit index mapping, use Array.from():

{#each Array.from({ length: count }, (_, i) => i) as i}
	<p>Iteration {i + 1}</p>
{/each}

All three variants produce exactly count iterations, regardless of surrounding component logic or reactive updates to the count variable.

Compiler Implementation Details

According to the sveltejs/svelte source code, the {#each} block undergoes three major processing phases:

These files confirm that the compiler treats the expression after {#each} as a generic iterable, meaning any technique that produces an array-like object of the correct length—whether via [...Array(n).keys()], Array.from(), or manual construction—is valid input for the EachBlock node.

Summary

  • Use [...Array(n).keys()] to generate a clean range of indices when you need to repeat a Svelte foreach block a specific number of times.
  • Inline Array(count) works when you only need the index and not the value.
  • The Svelte compiler (in packages/svelte/src/compiler/phases/3-transform/client/visitors/EachBlock.js) accepts any iterable, so custom array generators are fully supported.
  • All approaches are reactive and will re-render when the count variable changes.

Frequently Asked Questions

Can I use a regular for loop instead of {#each} in Svelte?

No, Svelte templates do not support JavaScript for loops directly. The {#each} block is the template syntax for iteration. You must generate an array of the desired length and use {#each} as shown above, which the compiler processes into optimized update loops in packages/svelte/src/compiler/phases/3-transform/client/visitors/EachBlock.js.

Does Svelte have a built-in range function like Python?

No, Svelte does not provide a built-in range() utility. You must implement the helper yourself (e.g., const range = n => [...Array(n).keys()]) or use the inline Array.from() patterns. This keeps the core compiler lightweight while allowing flexible JavaScript idioms.

Is there a performance difference between Array(n) and Array.from()?

For small to medium counts (under 1000), the performance difference is negligible. [...Array(n).keys()] and Array.from({ length: n }, (_, i) => i) both execute in microseconds. The Svelte runtime in packages/svelte/src/compiler/phases/3-transform/client/visitors/EachBlock.js processes the resulting arrays identically regardless of construction method.

How do I access the index when repeating a block N times?

The {#each} block always provides an optional second parameter for the index. When using {#each Array(count) as _, i}, the variable i contains the zero-based index. Alternatively, when mapping with Array.from(), you can return the index directly as the value: {#each Array.from({length: count}, (_, i) => i) as i}.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →