Group Controller [BETA]
A mute button for whole node groups — without re-running the graph
Let's be honest about what a "Group Controller" is: a power switch for a part of your workflow you keep turning off while you test. Every big ComfyUI graph has a handful of regions - the upscale chain, the second pass, a LoRA you're A/B testing - that you bypass and re-enable constantly. The stock way is right-click → bypass on a dozen nodes and try not to miss one. DA_GroupController collapses that into a row of toggles that flip entire groups at once, live in the browser, without ever re-queueing the prompt.
It lives in DemonAlone-JS_Addon-ComfyUI, the JavaScript-side companion pack to the author's main DemonAlone-nodes repo. The whole pack is deliberately JS-heavy so toggles, previews, and buttons respond without a page reload - and this node is the purest example. If you've used rgthree's Fast Groups Muter, the concept will feel familiar; this is the slot-based cousin of it, credited to a blend of AUN-ComfyUI-Nodes and rgthree's feature_group_fast_toggle.js.
How it actually works
The Python side barely does anything. It reads your slot settings and builds a list of which group titles should be on and which off, then hands that to JavaScript via a UI message. The JS (in web/GroupController.js) finds each LiteGraph group by its canvas title, collects the nodes sitting inside its bounding box, and flips each node's mode between ALWAYS (active), BYPASS, or NEVER (mute).
The important trick: the node declares IS_CHANGED as always false. That means toggling a switch never counts as a change, so the graph doesn't re-execute. You're editing state, not triggering a run - the whole point.
The inputs that matter
Only a handful do for most people. slot_count (1–20) sets how many control rows you see - 3 is the default and plenty for a starter. For each slot you get three fields:
targets_N- the group titles to hit, comma or semicolon separated (e.g.upscale, denoise). This is the one you actually type in.label_N- a name for the row so you remember slot 2 is "prepass", not "whatever I set up last Tuesday".switch_N- the 🟢/🔴 toggle itself. Only its value is a "real" input in the schema sense; the label and targets are strings it reads.
Then mode decides what an off state means: Bypass (runs data through untouched) or Mute (node stays live but its outputs are ignored). For most people Bypass is right; mute is for nodes whose wiring you can't skip. toggle_restriction offers max one (radio-button behavior - only one slot active at a time, good for A/B-ing branches) and always one (at least one must stay on). AllSwitch flips everything active at once.
The node has no outputs - it's a pure control panel, OUTPUT_NODE, nothing to wire downstream.
Installing it
Same as any pack. In ComfyUI Manager, search "DemonAlone-JS_Addon-ComfyUI" and install, or:
cd ComfyUI/custom_nodes
git clone https://github.com/DemonAlone/DemonAlone-JS_Addon-ComfyUI
Restart ComfyUI. No model files, no pip step, no heavy dependencies - the controller runs on browser JS plus the standard ComfyUI backend.
Where people get burned
The obvious one: targets are matched against the group's title, not the node names inside it. Rename the group and the slot goes quiet. The match is case-insensitive and exact on the group title, so Denoise won't catch a group called denoise_pass_2.
Second, this is a graph-organizing node, not a sampler or a loader. It does nothing unless you've bothered to name your groups. If you haven't, spend the two minutes to title them - that's the whole cost of entry. And if you're already deep into rgthree's Fast Groups dashboard, you may not need this at all; it's the same job with a different knob layout. But as a standalone switchboard that stays on one node, it's clean, it's instant, and it won't force a re-queue on you.
Inputs (65)
| Name | Type | Default | Description |
|---|---|---|---|
| modeopt | COMBO | Bypass | Choose how to disable nodes: Bypass (🔴) or Mute (🔇). |
| slot_countopt | INT | 31–20 | Number of control slots to show (1-20). |
| toggle_restrictionopt | COMBO | default | Logic for toggles: 'max one' allows only one active, 'always one' ensures at least one is active. |
| AllSwitchopt | BOOLEAN | false | ON = all groups active (🟢). OFF = use individual group switches. |
| show_AllSwitchopt | BOOLEAN | false | Show the AllSwitch toggle even in compact mode. |
| label_1opt | STRING | Descriptive label for slot 1 (other slots follow the same layout). | |
| targets_1opt | STRING | Target group Titles for slot 1 (comma or semicolon separated). Example: 'upscale, denoise' or 'preprocess; postprocess'. | |
| switch_1opt | BOOLEAN | false | Toggle state for slot 1. 🟢 = active, 🔴 = controlled by mode. |
| label_2opt | STRING | — | |
| targets_2opt | STRING | — | |
| switch_2opt | BOOLEAN | false | — |
| label_3opt | STRING | — | |
| targets_3opt | STRING | — | |
| switch_3opt | BOOLEAN | false | — |
| label_4opt | STRING | — | |
| targets_4opt | STRING | — | |
| switch_4opt | BOOLEAN | false | — |
| label_5opt | STRING | — | |
| targets_5opt | STRING | — | |
| switch_5opt | BOOLEAN | false | — |
| label_6opt | STRING | — | |
| targets_6opt | STRING | — | |
| switch_6opt | BOOLEAN | false | — |
| label_7opt | STRING | — | |
| targets_7opt | STRING | — | |
| switch_7opt | BOOLEAN | false | — |
| label_8opt | STRING | — | |
| targets_8opt | STRING | — | |
| switch_8opt | BOOLEAN | false | — |
| label_9opt | STRING | — | |
| targets_9opt | STRING | — | |
| switch_9opt | BOOLEAN | false | — |
| label_10opt | STRING | — | |
| targets_10opt | STRING | — | |
| switch_10opt | BOOLEAN | false | — |
| label_11opt | STRING | — | |
| targets_11opt | STRING | — | |
| switch_11opt | BOOLEAN | false | — |
| label_12opt | STRING | — | |
| targets_12opt | STRING | — | |
| switch_12opt | BOOLEAN | false | — |
| label_13opt | STRING | — | |
| targets_13opt | STRING | — | |
| switch_13opt | BOOLEAN | false | — |
| label_14opt | STRING | — | |
| targets_14opt | STRING | — | |
| switch_14opt | BOOLEAN | false | — |
| label_15opt | STRING | — | |
| targets_15opt | STRING | — | |
| switch_15opt | BOOLEAN | false | — |
| label_16opt | STRING | — | |
| targets_16opt | STRING | — | |
| switch_16opt | BOOLEAN | false | — |
| label_17opt | STRING | — | |
| targets_17opt | STRING | — | |
| switch_17opt | BOOLEAN | false | — |
| label_18opt | STRING | — | |
| targets_18opt | STRING | — | |
| switch_18opt | BOOLEAN | false | — |
| label_19opt | STRING | — | |
| targets_19opt | STRING | — | |
| switch_19opt | BOOLEAN | false | — |
| label_20opt | STRING | — | |
| targets_20opt | STRING | — | |
| switch_20opt | BOOLEAN | false | — |
Outputs (0)
No outputs