A JavaScript recursive generator is a function* that yields values while walking recursive data such as trees, menus, comments, folders, or nested JSON. The key operator is yield*, which delegates to another iterable or generator and makes recursive traversal clean.
Recursive generators are useful when you do not want to build the full result array immediately. They let callers consume values one at a time or convert the generated values to an array when needed.
Environment: Node.js v20.18.2. After each runnable snippet, the following paragraph states the expected console output (order and values).
Method 1: Create a Basic Generator Function
A generator function uses function* and pauses each time it reaches yield.
function* numbers() {
yield 1;
yield 2;
yield 3;
}
console.log([...numbers()]);You should see one line logging [ 1, 2, 3 ].
The spread operator converts the generator output into an array.
Method 2: Traverse a Tree with a Recursive Generator
Use yield* to call the same generator for child nodes.
function* walk(node) {
yield node.name;
for (const child of node.children ?? []) {
yield* walk(child);
}
}
const tree = {
name: "root",
children: [
{ name: "docs", children: [{ name: "index.md" }] },
{ name: "src" },
],
};
console.log("generator-walk:", [...walk(tree)].join(" > "));You should see one line logging generator-walk: root > docs > index.md > src.
This is a depth-first traversal. Each node is yielded before its children.
Method 3: Convert a Generator to an Array
A generator is iterable, so you can use Array.from() or the spread operator.
const names = Array.from(walk(tree));
console.log(names);You should see one line logging [ 'root', 'docs', 'index.md', 'src' ].
Use an array when you need methods such as map(), filter(), or join(). Keep the generator form when you want lazy iteration.
Method 4: Search with a Recursive Generator
Because generators yield values one at a time, you can stop as soon as a match is found.
for (const name of walk(tree)) {
if (name.endsWith(".md")) {
console.log(name);
break;
}
}You should see one line logging index.md.
This avoids traversing more data than needed after the first match.
Common Questions About Recursive Generators
What does yield* do in JavaScript?
yield* delegates yielding to another iterable or generator. In recursive generators, it is commonly used to yield all values from a recursive call.
Can generator functions be arrow functions?
No. JavaScript does not support arrow generator functions. Use function* name() { ... } or function* () { ... }.
When should I use a recursive generator?
Use it when data is nested and you want to traverse it lazily, such as folder trees, menu trees, comment threads, and nested objects.
Summary
A JavaScript recursive generator combines function*, yield, and yield* to traverse nested data cleanly. It is especially useful for tree traversal because callers can consume values lazily, stop early, or convert the results to an array only when needed.
