EmAySee Text Combiner
Join up to 50 strings with newlines before they hit your prompt encoder
- text
ComfyUI workflows have a habit of growing string sources like weeds: a wildcard picker, an LLM output, a fixed style block, a tag list, a negative-prompt section. At some point they all need to land in the same CLIP Text Encode, and a single STRING input takes one string. EmAySee Text Combiner is the gather node for that job: up to fifty optional string inputs, joined with newlines, one string out. It's the "collect all the prompt parts" node in this pack, and for prompt-assembly workflows it's genuinely the right tool.
The fifty-cap matters more than it sounds like it should. Most text-combiner nodes top out around five or ten inputs; this one lets you wire a whole prompt architecture - subject, style, quality tags, lighting, camera, artist block, negative section - without stringing multiple combiners in series. Newlines are the separator (not commas, not spaces), so it suits multi-line prompt styles. If you want commas, join first with the pack's Text Replace or do it in a different combiner.
How it works
Every one of text_1 through text_50 is optional and force-input (you can't type into them - they're meant to be wired). The node walks them in order, skips any that are None or empty, and joins the rest with "\n":
return ("\n".join(text_list),)
That's the entire mechanism. Order is preserved, empty inputs are silently dropped, and the output is a single text string.
The inputs that matter
Honestly, none of them are special - they're all "text_N" and they all behave identically. What matters is the discipline you bring: keep a convention for which slot does what (slots 1-5 for subject blocks, 6-10 for style, etc.) so a workflow stays readable. The output, text, wires into your CLIP Text Encode's prompt input, or into another text node upstream of it.
One thing to know: because every input is forceInput, you can't use this node to hand-type a fixed string into a slot. If you want to include a constant block, pipe it through a simple text node first - which, in this pack, means running a string literal through any string passthrough or the Text Replace node with empty find/replace pairs.
Installing it
Standard for this pack: ComfyUI_EmAySee_CustomNodes via ComfyUI Manager, or git clone https://github.com/EmAySee/ComfyUI_EmAySee_CustomNodes into custom_nodes/, restart. No dependencies, no models - pure string joining.
Where people get burned
The newline separator is the main gotcha: if your downstream expects comma-separated tags, this node will hand you newline-separated output, which some tag consumers choke on. Route through a join/transform node if you need commas. Also, fifty inputs is a lot of widget noise on the graph - for most workflows you'll use five or six slots and leave the rest empty, and empties are skipped, so that's fine. But a stray space or line-break in a single input will land in the middle of your joined prompt, so keep your source strings clean upstream. If your combiner output starts with a blank line, check for a source node that outputs whitespace.
Inputs (50)
| Name | Type | Default | Description |
|---|---|---|---|
| text_1opt | STRING | — | |
| text_2opt | STRING | — | |
| text_3opt | STRING | — | |
| text_4opt | STRING | — | |
| text_5opt | STRING | — | |
| text_6opt | STRING | — | |
| text_7opt | STRING | — | |
| text_8opt | STRING | — | |
| text_9opt | STRING | — | |
| text_10opt | STRING | — | |
| text_11opt | STRING | — | |
| text_12opt | STRING | — | |
| text_13opt | STRING | — | |
| text_14opt | STRING | — | |
| text_15opt | STRING | — | |
| text_16opt | STRING | — | |
| text_17opt | STRING | — | |
| text_18opt | STRING | — | |
| text_19opt | STRING | — | |
| text_20opt | STRING | — | |
| text_21opt | STRING | — | |
| text_22opt | STRING | — | |
| text_23opt | STRING | — | |
| text_24opt | STRING | — | |
| text_25opt | STRING | — | |
| text_26opt | STRING | — | |
| text_27opt | STRING | — | |
| text_28opt | STRING | — | |
| text_29opt | STRING | — | |
| text_30opt | STRING | — | |
| text_31opt | STRING | — | |
| text_32opt | STRING | — | |
| text_33opt | STRING | — | |
| text_34opt | STRING | — | |
| text_35opt | STRING | — | |
| text_36opt | STRING | — | |
| text_37opt | STRING | — | |
| text_38opt | STRING | — | |
| text_39opt | STRING | — | |
| text_40opt | STRING | — | |
| text_41opt | STRING | — | |
| text_42opt | STRING | — | |
| text_43opt | STRING | — | |
| text_44opt | STRING | — | |
| text_45opt | STRING | — | |
| text_46opt | STRING | — | |
| text_47opt | STRING | — | |
| text_48opt | STRING | — | |
| text_49opt | STRING | — | |
| text_50opt | STRING | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| text | STRING | — |