Mie Loop Start ๐
A real for-loop inside a ComfyUI graph
- loop_ctx
- index
- count
- is_last
ComfyUI runs your graph once, top to bottom, and stops. There's no for, no while, no native way to say "do this three times with a different value each pass." So people copy-paste the same cluster of nodes over and over, or give up and drive the whole thing from the ComfyUI API in Python. If you've ever asked "is there a trick for repetitive tasks in Comfy" - this is the node that answers it. MieLoopStart is the head of the loop. It opens an iteration, hands you the current value and index, and the matching MieLoopEnd at the other end keeps re-running the body until the sequence is exhausted.
Part of ComfyUI-MieNodes (ComfyUI_MieNodes), MieMieeeee's utility pack, under the ๐ Loop submenu.
How it works
You tell Start two things: what kind of value you're looping over and how to generate the sequence.
param_type-int,float,string, orjson. The type of the value each iteration produces.param_mode-list,range, ordecrement.listwalks explicit values you type in;rangecounts from a start to an end by a step;decrementstarts from a total and subtracts a step each pass (handy for countdowns or draining a budget).
Depending on those two, you fill in the matching field: int_list / float_list / string_list / json_list for list mode (defaults like 1,2,3 and one-item-per-line for strings), or the int_range_start/end/step and float_range_* triples for range, or the *_decrement_total / *_decrement_step pair for decrement. You only touch the set that matches your param_type + param_mode; the rest sit unused.
The output that matters is loop_ctx - a MIE_LOOP_CTX object that is the spine of the whole system. It carries the current value, the index, the total count, and a shared state bag, and it threads through every other loop node. Everything downstream reads from it. Start also emits index (0-based current position), count (total iterations), and is_last (true on the final pass) as plain outputs so you don't need a separate accessor for the common cases.
Inside the loop body, you pull the current value with a MieLoopParamGet node, do your work, and route loop_ctx into MieLoopEnd to close it.
The inputs that matter
loop_id(defaultloop_1) - the name that ties this loop's state together. Leave it alone for a single loop; give each loop its own id if you run more than one so their state doesn't collide.param_type+param_mode- the two dropdowns above. Set these first; they decide which value fields you fill.initial_state_json(default{}) - seed the shared state bag with starting key/values, readable later with the ParamGet nodes. Optional but this is how you carry extra data (flags, counters) alongside the iterated value.
There's also meta_json for attaching metadata and resume_loop_ctx for restarting a loop from a saved context (paired with MieLoopResume) - both niche, both fine to ignore at first.
Installing it
ComfyUI Manager โ search ComfyUI-MieNodes โ install โ restart. Or:
cd ComfyUI/custom_nodes
git clone https://github.com/MieMieeeee/ComfyUI-MieNodes
then restart. The Loop nodes are pure Python - no model downloads, no heavy dependencies (the LLM providers and Florence2 the README talks about are for other nodes in the pack, not these). They land under ๐ MieNodes โ ๐ Loop.
Common issues
Nothing loops - it runs once and stops. Start doesn't drive iteration by itself. You need MieLoopEnd wired to loop_ctx at the tail; End is the piece that re-runs the body. Start alone just sets up the first pass.
Your list isn't being parsed the way you expect. Match param_type to the field you filled. A string list is newline-separated; the numeric lists are comma-separated. Filling float_list while param_type is int means your values never get read.
Two loops fighting each other. If you have more than one loop in a graph, give them distinct loop_ids. Sharing the default loop_1 makes their state step on each other.
Inputs (20)
| Name | Type | Default | Description |
|---|---|---|---|
| loop_id | STRING | loop_1 | โ |
| param_type | COMBO | int | 4 options: int, float, string, json |
| param_mode | COMBO | list | 3 options: list, range, decrement |
| initial_state_jsonopt | STRING | {} | โ |
| int_listopt | STRING | 1,2,3 | โ |
| float_listopt | STRING | 0.1,0.2,0.3 | โ |
| string_listopt | STRING | item_1 item_2 item_3 | โ |
| json_listopt | STRING | [{"value": 1}, {"value": 2}, {"value": 3}] | โ |
| int_range_startopt | INT | 1 | โ |
| int_range_endopt | INT | 3 | โ |
| int_range_stepopt | INT | 1 | โ |
| float_range_startopt | FLOAT | 0.10 | โ |
| float_range_endopt | FLOAT | 0.30 | โ |
| float_range_stepopt | FLOAT | 0.10 | โ |
| int_decrement_totalopt | INT | 5 | โ |
| int_decrement_stepopt | INT | 2 | โ |
| float_decrement_totalopt | FLOAT | 5.00 | โ |
| float_decrement_stepopt | FLOAT | 2.00 | โ |
| meta_jsonopt | STRING | {} | โ |
| resume_loop_ctxopt | STRING | โ |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| loop_ctx | MIE_LOOP_CTX | โ |
| index | INT | โ |
| count | INT | โ |
| is_last | BOOLEAN | โ |