Word Joiner
The invisible-character hack that keeps tokenizers from splitting terms
- joined_text
This is the oddest node in the pack's text corner, and it does exactly one thing: it inserts the Unicode WORD JOINER character (U+2060) between every pair of adjacent characters in your text, and tucks a joiner around the whole string too. The result looks identical on screen - U+2060 is zero-width and invisible - but to a tokenizer it's a different string. The node name says "Word Joiner," the honest description is "invisible glue."
Why would you want that? Modern text encoders and VLMs tokenize aggressively, and a term you care about - a character name, a style phrase, a compound word - can get split into pieces the model then re-weights or mangles. The word joiner is a signal that characters belong together: it's the same character your word processor drops in so a phone number doesn't line-break in the middle. In a prompt pipeline it's a way to tell the tokenizer "these characters are one unit." Some people use it to protect a specific name from being broken across tokens; this pack even ships a sibling node, UC_UnWordJoiner, to strip the joiners back out.
The mechanism is a one-liner: a regex replaces every non-joiner character followed by another non-joiner with the character plus a joiner, so the whole string becomes joiner c1 joiner c2 joiner ... cN joiner. Every character is now separated from its neighbors by an unbreakable, non-printing mark.
Input and output
- text (multiline STRING) - the string to glue together.
- joined_text (STRING) - the same text with joiners inserted. Wire it anywhere you'd wire the original: into a text encode, a VLM query, a filename builder.
Installing it
Part of ComfyUI-UtilsCollection - Manager search, or:
cd ComfyUI/custom_nodes
git clone https://github.com/silveroxides/ComfyUI-UtilsCollection
Restart, done. Deps are just opencv-python and typing-extensions; nothing to download.
The honest caveats
This is a hack, and it's a fiddly one. First, the joiners are invisible, so when something goes wrong it's very hard to see why - your prompt looks identical and behaves differently. That's when you reach for UC_UnWordJoiner to confirm the joiners are there. Second, not every tokenizer treats U+2060 the way you hope: an LLM encoder may just emit a new token for it, shifting your text in ways you didn't intend rather than protecting a word. The result is that this node is genuinely useful in specific pipelines and pointless noise in others - if you add it and outputs don't change, it's not broken, the encoder just doesn't care. Test it on one term before you commit a whole workflow to it. When it works, though, it's the kind of invisible fix you'd never have thought to reach for.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| text | STRING | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| joined_text | STRING | — |