LoRA Stacker (CharacterSuite)
Ten LoRAs, One Node, and It Tells You the Trigger Words
- model
- clip
- model
- clip
- trigger_prompt
The LoRA Stacker (CharacterSuite) is the most ambitious node in the comfyui-character-suite pack, because it's the only one that reaches outside your machine. The rest of the suite is pure local text juggling; this one talks to CivitAI to fetch the trigger words for each LoRA you stack, caches them, and shows them to you as clickable chips. Ten LoRA slots in a single node, per-slot bypass, separate model and clip strengths - the whole package.
If you've used rgthree's Power Lora Loader, you know the shape of the thing (the KB's ecosystem material calls it the LoRA-stacking benchmark). The difference here is the trigger-word picker being built in rather than an afterthought in a right-click menu.
Why you'd stack LoRAs at all
Character consistency is a LoRA problem (the KB's character-consistency work is clear: LoRA is the gold standard for a character you'll reuse), but nobody runs just a character LoRA. You want the character LoRA plus a style LoRA plus a detail enhancer, and suddenly you're chaining three loader nodes into each other. This node collapses that into one place with a bypass toggle per slot, so you can A/B whether style_lora is helping by flipping one checkbox instead of rewiring.
How it works
Each lora_N dropdown is populated from your ComfyUI/models/loras folder. Pick one and the node SHA256-hashes the file and queries CivitAI's model-versions/by-hash endpoint for the model's trained trigger words, then caches them in data/loras_tags.json inside the pack folder. A background scan at startup warms the cache for your whole library so the picker doesn't stall the first time you use it. The companion JS widget renders the tags as chips you click to add to your prompt; the selected set lands in selected_tags, which merges with opt_prompt into the trigger_prompt output - wire that into your prompt encoder and your LoRA's trigger word is never forgotten again.
The inputs that matter:
model/clip- required, from your checkpoint loader. Feed them in, get them back with LoRAs applied.lora_1…lora_10, each withstrength_model_Nandstrength_clip_N(default 1, range −10 to 10) - the model strength bends the diffusion UNet, the clip strength bends the text encoder. Separating them is the whole reason people stack instead of using one combined value: some style LoRAs want clip strength ~0.5 with model strength at 1.bypass_N- flip to skip a slot without deleting your settings.force_fetch_N- force a fresh CivitAI lookup for that slot (the cache normally refreshes on a schedule).
Outputs: model and clip (looped through as many slots as you populated) plus trigger_prompt (STRING).
Installing it
cd ComfyUI/custom_nodes/
git clone https://github.com/DrkSun81/comfyui-character-suite
Restart and it's under CharacterSuite (or ComfyUI Manager → search "character suite"). No pip requirements - stdlib only, and requests is optional; without it the CivitAI call falls back to urllib. Python 3.9+.
Where it gets you
- Trigger words depend on the hash matching CivitAI. A locally-trained LoRA, or one you renamed, will fetch nothing - the cache then records "we know there are no tags" and won't hammer the API again for days, so you'll be typing those trigger words by hand into
selected_tags. That's fine, just know the picker isn't magic. - First run per LoRA hits the network. New files trigger a fetch with retries and a 3-day cooldown on failures. If you're offline, it degrades gracefully and keeps whatever's cached - but the tag picker will be empty for anything never fetched before.
- This is the one network-facing node in the pack. Everything else is local. It only talks to CivitAI's public API for tag lookups, but it's worth knowing which of your nodes phones home, especially if you're the suspicious type about arbitrary Python (and you should be, per the KB's security notes on the ecosystem).
- The 1.1.1 changelog fixed "None" landing in strength fields - the old build could desync its widgets. If you see a slot refusing to apply, make sure you're on the latest revision.
It's a young node in a young pack (mid-2026, no community track record yet), so treat it as the tool it is: a tidy way to stack a character LoRA, a style LoRA, and a detail LoRA without a wall of nodes - with a built-in cheat sheet for the trigger words you always forget.
Inputs (54)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | — | |
| clip | CLIP | — | |
| opt_promptopt | STRING | — | |
| lora_1opt | COMBO | None | 1 options: None |
| strength_model_1opt | FLOAT | 1.00-10–10 | — |
| strength_clip_1opt | FLOAT | 1.00-10–10 | — |
| bypass_1opt | BOOLEAN | false | — |
| force_fetch_1opt | BOOLEAN | false | — |
| lora_2opt | COMBO | None | 1 options: None |
| strength_model_2opt | FLOAT | 1.00-10–10 | — |
| strength_clip_2opt | FLOAT | 1.00-10–10 | — |
| bypass_2opt | BOOLEAN | false | — |
| force_fetch_2opt | BOOLEAN | false | — |
| lora_3opt | COMBO | None | 1 options: None |
| strength_model_3opt | FLOAT | 1.00-10–10 | — |
| strength_clip_3opt | FLOAT | 1.00-10–10 | — |
| bypass_3opt | BOOLEAN | false | — |
| force_fetch_3opt | BOOLEAN | false | — |
| lora_4opt | COMBO | None | 1 options: None |
| strength_model_4opt | FLOAT | 1.00-10–10 | — |
| strength_clip_4opt | FLOAT | 1.00-10–10 | — |
| bypass_4opt | BOOLEAN | false | — |
| force_fetch_4opt | BOOLEAN | false | — |
| lora_5opt | COMBO | None | 1 options: None |
| strength_model_5opt | FLOAT | 1.00-10–10 | — |
| strength_clip_5opt | FLOAT | 1.00-10–10 | — |
| bypass_5opt | BOOLEAN | false | — |
| force_fetch_5opt | BOOLEAN | false | — |
| lora_6opt | COMBO | None | 1 options: None |
| strength_model_6opt | FLOAT | 1.00-10–10 | — |
| strength_clip_6opt | FLOAT | 1.00-10–10 | — |
| bypass_6opt | BOOLEAN | false | — |
| force_fetch_6opt | BOOLEAN | false | — |
| lora_7opt | COMBO | None | 1 options: None |
| strength_model_7opt | FLOAT | 1.00-10–10 | — |
| strength_clip_7opt | FLOAT | 1.00-10–10 | — |
| bypass_7opt | BOOLEAN | false | — |
| force_fetch_7opt | BOOLEAN | false | — |
| lora_8opt | COMBO | None | 1 options: None |
| strength_model_8opt | FLOAT | 1.00-10–10 | — |
| strength_clip_8opt | FLOAT | 1.00-10–10 | — |
| bypass_8opt | BOOLEAN | false | — |
| force_fetch_8opt | BOOLEAN | false | — |
| lora_9opt | COMBO | None | 1 options: None |
| strength_model_9opt | FLOAT | 1.00-10–10 | — |
| strength_clip_9opt | FLOAT | 1.00-10–10 | — |
| bypass_9opt | BOOLEAN | false | — |
| force_fetch_9opt | BOOLEAN | false | — |
| lora_10opt | COMBO | None | 1 options: None |
| strength_model_10opt | FLOAT | 1.00-10–10 | — |
| strength_clip_10opt | FLOAT | 1.00-10–10 | — |
| bypass_10opt | BOOLEAN | false | — |
| force_fetch_10opt | BOOLEAN | false | — |
| selected_tagsopt | STRING | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| model | MODEL | — |
| clip | CLIP | — |
| trigger_prompt | STRING | — |