react-loop-z is a lightweight, type-safe, declarative looping toolkit for React.
It helps you replace .map() chains and manual iteration logic with
clean, expressive JSX blocks.
Write loops like logic. Render JSX like structure.
- Declarative JSX loops
- Strict TypeScript support
- Zero dependencies
- Tree-shakable
- Infinite loop protection (safe guards)
- SSR & StrictMode safe
- Tiny bundle size
- Pure function components
- No internal state machines
- No proxies or runtime magic
- Strict generic typing
- Guard-based loop safety
Each loop is an independent, tree-shakable unit. Import only what you use.
npm install react-loop-zimport { For } from "react-loop-z";
<For
of={["foo", "bar"]}
>
{(item, index) => (
<span key={index}>Hello, {item}</span>
)}
</For>Type-safe example:
type User = { id: number; name: string };
<For<User> of={users}>
{(user) => <div key={user.id}>{user.name}</div>}
</For>import { RangeLoop } from "react-loop-z";
<RangeLoop from={0} to={5}>
{(i) => <div key={i}>{i}</div>}
</RangeLoop>import { While } from "react-loop-z";
let i = 0;
<While
condition={() => i++ < 3}
>
{(index) => <div key={index}>Count {index}</div>}
</While>import { Do } from "react-loop-z";
let i = 0;
<Do
condition={() => i < 3}
>
{(index) => {
i++;
return <div key={index}>Count {index}</div>;
}}
</Do>import { MapLoop } from "react-loop-z";
<MapLoop of={new Map([["a", 1], ["b", 2]])}>
{(value, key) => (
<div key={key}>
{key}: {value}
</div>
)}
</MapLoop>import { SetLoop } from "react-loop-z";
<SetLoop of={new Set(["foo", "bar"])}>
{(item) => <div key={item}>{item}</div>}
</SetLoop>import { ObjectLoop } from "react-loop-z";
<ObjectLoop of={{ a: 1, b: 2 }}>
{(value, key) => (
<div key={key}>
{key}: {value}
</div>
)}
</ObjectLoop>While, Do, and numeric loops include safety guards to prevent
runaway infinite loops in development.
Always ensure your condition eventually becomes false.
Declarative loop with early exit support (like break in JavaScript).
<BreakableLoop items={users}>
{(user, { breakLoop }) => {
if (!user.active) breakLoop()
return <UserCard user={user} />
}}
</BreakableLoop>Render conditionally without chaining .filter().map().
<FilterLoop items={products} when={(p) => p.inStock}>
{(product) => <ProductItem product={product} />}
</FilterLoop>Split an array into chunks (ideal for grid or row rendering).
<ChunkLoop items={posts} size={3}>
{(chunk) => (
<div className="row">
{chunk.map(post => <PostCard key={post.id} {...post} />)}
</div>
)}
</ChunkLoop>Render only the first N elements (lightweight alternative to slice).
<TakeLoop items={messages} count={5}>
{(msg) => <MessageItem message={msg} />}
</TakeLoop>Remove duplicates by key selector before rendering.
<UniqueLoop items={users} by={(u) => u.email}>
{(user) => <UserRow user={user} />}
</UniqueLoop>Flatten nested arrays before rendering.
<FlatLoop items={nestedComments}>
{(comment) => <CommentItem comment={comment} />}
</FlatLoop>Supports async iterables, promises, or async generators with built-in async handling.
<AsyncLoop items={fetchUsers()}>
{(user) => <UserCard user={user} />}
</AsyncLoop>Or:
<AsyncLoop items={asyncGenerator()}>
{(value) => <div>{value}</div>}
</AsyncLoop>Declarative numeric range loop.
<RangeLoop from={1} to={5}>
{(i) => <div>{i}</div>}
</RangeLoop>Render N times (simple repeat utility).
<TimesLoop times={3}>
{(index) => <Skeleton key={index} />}
</TimesLoop>| Feature | react-loop-z | react-loops | react-for | Native .map() |
|---|---|---|---|---|
| Declarative JSX Blocks | β | β | β | β |
| Strong TypeScript Inference | β | |||
| Array Loop | β | β | β | β |
| Numeric / Range Loop | β | β | β | |
| While / Do Loop | β | β | ||
| Map / Set / Object Support | β | β Iterable | ||
| Break Control | β | β | β | β |
| Async Loop | β | β | β | β |
| Infinite Loop Protection | β | β | β | β |
| Zero Runtime Dependencies | β | β | β | |
| Tree-Shakable | β | β | β | β |
A declarative loop control system for React β not just array mapping.
- Keep rendering pure
- Keep iteration declarative
- Keep bundle tiny
- Keep logic readable
Iteration belongs to structure, not utility chains.
react-loop-z is not trying to replace .map().
It provides:
- Structure-driven iteration
- Declarative control flow
- Composable loop primitives
Think of it as: Control flow components for React.
MIT