Nodes/DemonAlone-JS_Addon-ComfyUI/Group Controller [BETA]
ComfyUI Node

Group Controller [BETA]

A mute button for whole node groups — without re-running the graph

By DemonAlone·Created about a month ago·Updated a day ago· 1
Group Controller [BETA]
      modeBypass
      slot_count3
      toggle_restrictiondefault
      AllSwitchfalse
      show_AllSwitchfalse
      label_1
      targets_1
      switch_1false
      label_2
      targets_2
      switch_2false
      label_3
      targets_3
      switch_3false
      label_4
      targets_4
      switch_4false
      label_5
      targets_5
      switch_5false
      label_6
      targets_6
      switch_6false
      label_7
      targets_7
      switch_7false
      label_8
      targets_8
      switch_8false
      label_9
      targets_9
      switch_9false
      label_10
      targets_10
      switch_10false
      label_11
      targets_11
      switch_11false
      label_12
      targets_12
      switch_12false
      label_13
      targets_13
      switch_13false
      label_14
      targets_14
      switch_14false
      label_15
      targets_15
      switch_15false
      label_16
      targets_16
      switch_16false
      label_17
      targets_17
      switch_17false
      label_18
      targets_18
      switch_18false
      label_19
      targets_19
      switch_19false
      label_20
      targets_20
      switch_20false

      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.

      CategoryNode Control

      Inputs (65)

      NameTypeDefaultDescription
      modeoptCOMBOBypassChoose how to disable nodes: Bypass (🔴) or Mute (🔇).
      slot_countoptINT31–20Number of control slots to show (1-20).
      toggle_restrictionoptCOMBOdefaultLogic for toggles: 'max one' allows only one active, 'always one' ensures at least one is active.
      AllSwitchoptBOOLEANfalseON = all groups active (🟢). OFF = use individual group switches.
      show_AllSwitchoptBOOLEANfalseShow the AllSwitch toggle even in compact mode.
      label_1optSTRINGDescriptive label for slot 1 (other slots follow the same layout).
      targets_1optSTRINGTarget group Titles for slot 1 (comma or semicolon separated). Example: 'upscale, denoise' or 'preprocess; postprocess'.
      switch_1optBOOLEANfalseToggle state for slot 1. 🟢 = active, 🔴 = controlled by mode.
      label_2optSTRING
      targets_2optSTRING
      switch_2optBOOLEANfalse
      label_3optSTRING
      targets_3optSTRING
      switch_3optBOOLEANfalse
      label_4optSTRING
      targets_4optSTRING
      switch_4optBOOLEANfalse
      label_5optSTRING
      targets_5optSTRING
      switch_5optBOOLEANfalse
      label_6optSTRING
      targets_6optSTRING
      switch_6optBOOLEANfalse
      label_7optSTRING
      targets_7optSTRING
      switch_7optBOOLEANfalse
      label_8optSTRING
      targets_8optSTRING
      switch_8optBOOLEANfalse
      label_9optSTRING
      targets_9optSTRING
      switch_9optBOOLEANfalse
      label_10optSTRING
      targets_10optSTRING
      switch_10optBOOLEANfalse
      label_11optSTRING
      targets_11optSTRING
      switch_11optBOOLEANfalse
      label_12optSTRING
      targets_12optSTRING
      switch_12optBOOLEANfalse
      label_13optSTRING
      targets_13optSTRING
      switch_13optBOOLEANfalse
      label_14optSTRING
      targets_14optSTRING
      switch_14optBOOLEANfalse
      label_15optSTRING
      targets_15optSTRING
      switch_15optBOOLEANfalse
      label_16optSTRING
      targets_16optSTRING
      switch_16optBOOLEANfalse
      label_17optSTRING
      targets_17optSTRING
      switch_17optBOOLEANfalse
      label_18optSTRING
      targets_18optSTRING
      switch_18optBOOLEANfalse
      label_19optSTRING
      targets_19optSTRING
      switch_19optBOOLEANfalse
      label_20optSTRING
      targets_20optSTRING
      switch_20optBOOLEANfalse

      Outputs (0)

      No outputs