∞ Text Concatenate
Glue Together as Many Prompt Parts as You Want
- STRING
The text-joining node that grows ports as you connect
Every serious ComfyUI user eventually ends up with a prompt that's assembled from parts - a base scene, a subject, a style tag, a lighting bit - each tweaked independently. The tedious part is the glue: some node to jam them together with commas. ∞ Text Concatenate (class Moon_NE_Text_Concatenate, from Moon-NE's MoonNe_Nodes pack) is a perfectly good version of that glue with one distinctive trick: the input ports are infinite and self-growing.
Wire a string into text_0 and a text_1 port materializes. Wire that and text_2 appears. Unplug a middle one and the empty trailing ports collapse. It's the "∞" in the name made literal - you never run out of inputs, and you never have to deal with a fixed bank of unused slots. That's the whole reason to reach for this over the stock concatenation nodes: if you keep reordering and re-adding prompt fragments, not having to resize or re-wire is genuinely nicer.
The other text-joining options in the ecosystem exist - this is the same utility class as rgthree's text utilities, which are installed by roughly everyone - but those tend to have a fixed number of inputs baked into the node. This one gambles on a JavaScript extension (in the pack's js/ folder) that watches your connections and appends inputs on the fly. When it works it feels like magic; when it doesn't, it's almost always the frontend not loading (see below).
How it works
Behind the scenes the node plays a small trick to make the infinite ports legal. ComfyUI's backend validates inputs strictly, and dynamically-added text_N ports don't exist in the node's declared schema. The node gets around that with a dict subclass that fakes a type definition for any key you wire in, plus a VALIDATE_INPUTS that swallows everything. It's hacky but effective - and it's why this node (and its sibling batch random text, which shares the trick) can accept arbitrary numbers of inputs without crashing the graph validator.
At execution time it collects every text_* input, sorts them numerically, and joins them with your delimiter. Two settings you'll actually touch:
- delimiter - default
,(comma-space), the standard prompt joiner. Type\n(or paste an actual newline) and it converts to a line break, which is handy for building multi-line structured prompts for the modern instruction-style models. - clean_whitespace -
true/false. On, it strips each fragment before joining, so sloppy trailing spaces never producetag, tag-style double gaps.
Optional text_0 is where you start; the rest appear as you connect. Output is a single STRING - the joined prompt - and it feeds straight into a CLIP Text Encode.
The one gotcha
The dynamic ports are a frontend feature, added by the JS extension when the node loads. If you open a workflow and the extra text_N inputs are missing, or a saved workflow seems to have lost them, that's the browser not having the extension loaded - hard-refresh the tab (or restart ComfyUI) before suspecting the node. Everything else is quiet, standard text-node behavior: empty fragments are skipped, and there are no dependencies or model downloads in the pack at all.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/Moon-NE/MoonNe_Nodes
Or, easier, open ComfyUI Manager, search MoonNe_Nodes, and hit Install. Either way, restart ComfyUI afterward so the JS extension registers. If you assemble prompts from parts - and honestly, who doesn't - this is the laziest glue on the shelf.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| delimiter | STRING | , | — |
| clean_whitespace | COMBO | 2 options: true, false | |
| text_0opt | STRING | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| STRING | STRING | — |