Dynamic Pipe Any Node
A pipe that's just a list — build it, pad it, unpack it
- pipe
- pipe
ComfyUI has a whole family of "pipe" nodes - rgthree's Context, Efficiency's bundled model/clip/vae tuple - and they're all the same idea: gather a bundle of values onto one wire so a graph doesn't become forty parallel noodles. This node is the generic version. A pipe here is literally just a Python list, no special structure, no model/clip/vae contract. You build a list, ship it down one wire, and pull it apart at the other end.
That sounds almost too simple, but it's exactly what you want when you're feeding data into the pack's DynamicScriptNode: drop a list of prompts, conditioning, or numbers into one port, do real work on it in Python, and hand it back out. Because the pipe is a plain list, every other *-typed node can touch it - it doesn't commit you to any pack's pipe format.
How it behaves
Set ports_count (0–100) and the node grows a matching set of ports. Each run it:
- Takes your incoming
pipe(any Python list - or nothing). - Pads it with
Nones if it's shorter thanports_count, or trims it if longer. - Overwrites positions with any connected
input_*port that isn'tNone. - Outputs the finished list as
pipe, plus every item on its ownoutput_*port.
So the input_* ports are "patch" inputs - they replace slots in the list rather than append to it - and the output_* ports are the unpack. Wire the whole list into one place, or unpack individual slots into separate consumers. Both, if you like; the node is happy to serve the list and its parts simultaneously.
Note that the fixed schema only lists the single pipe output - the output_* and input_* ports are generated dynamically by ports_count, which is why you won't see them enumerated anywhere.
The inputs and outputs that matter
ports_count- the size of the list and the number of port pairs. This is the one you actually set.pipe(optional) - the incoming list. Accepts any Python list; leave it unwired to start from an empty list.pipeoutput - the final list.output_*- each list element on its own socket.
Where people get burned
Noneslots are meaningful, not an error. If a slot ends upNone, that's the value - downstream nodes that choke onNonewill choke. That's also the difference from a merge: this node doesn't concatenate lists, it positions items.- It always reruns. Change-detection returns
NaN, so the node rebuilds the pipe every queue run and marks everything downstream dirty. Cheap for a list, but don't hang a chain of these off a huge workflow and wonder why the cache never engages. - It's not a context bus. It won't carry a model alongside a latent in one typed bundle the way rgthree's
Contextdoes; it's a dumb list. If you need typed bundle semantics, that's a different node - use this one when "just a list" is exactly the point.
Install
Same pack, zero dependencies:
cd ComfyUI/custom_nodes
git clone https://github.com/inkbottle-9/comfyui_dynamic.git
restart, or search comfyui_dynamic in ComfyUI Manager. A small, solo-maintained, LGPL pack - the pipe node is one of its simplest and most dependable parts.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| ports_count | INT | 20–100 | The number of port-pair for this node. |
| pipeopt | * | The pipe in. Accept any Python list or tuple. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| pipe | * | Essentially outputs a Python list. |