From comfyui-plugin
ComfyUI routing nodes: typed switches, index switches, broadcast (Anything Everywhere), pipe/context bundles, for/while loops, ExecutionBlocker gates. Use when wiring where a signal routes in a workflow.
How this skill is triggered — by the user, by Claude, or both
Slash command
/comfyui-plugin:comfy-flow-controlThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Routing, switching, broadcast, bundling, looping, gating. *Where does
Routing, switching, broadcast, bundling, looping, gating. Where does the signal go once the decision is made.
Six packs on this install contribute flow-control primitives. Each has overlapping options and pack-specific quirks — the goal of this skill is to pick the right one in one decision, not browse a dropdown.
| Use this skill when... | Use instead when... |
|---|---|
| Wiring how a signal routes, switches, broadcasts, loops, or is gated | Forming the predicate that drives the route -> comfy-conditionals |
| Picking a switch / index-switch / broadcast node | Debugging or inspecting a routed value -> comfy-debug-preview |
custom_nodes/rgthree-comfy/__init__.py — context bundles, Any Switch, Power Lora Loader, fast groups muter (frontend-only)custom_nodes/cg-use-everywhere/__init__.py — broadcast "Anything Everywhere" sentinelscustom_nodes/ComfyUI-Crystools/crystools/nodes_switch.py — type-typed CSwitchBoolean* familycustom_nodes/comfyui-impact-pack/modules/impact/special_samplers.py and core.py — ImpactSwitch (GeneralSwitch/GeneralInversedSwitch), ImpactConditionalBranch, ExecutionOrderControllercustom_nodes/comfyui-easy-use/py/nodes/logic.py and flow.py — easy switches, pipes, forLoop, whileLoop, blockerComfySwitchNode (boolean toggle between two same-type inputs)| You have… | Selector | Best node | Why |
|---|---|---|---|
| 2 IMAGE inputs, BOOLEAN selector | bool | easy imageSwitch or Crystools CSwitchBooleanImage | Lazy: only the chosen branch runs |
| 2 ANY inputs, BOOLEAN selector | bool | Crystools CSwitchBooleanAny | Lazy; cleanest signature |
| 2 STRING inputs, BOOLEAN selector | bool | easy textSwitch or Crystools CSwitchBooleanString | Both lazy |
| 2 CONDITIONING inputs, BOOLEAN | bool | Crystools CSwitchBooleanConditioning | Lazy; native CONDITIONING type |
| 2 LATENT / MASK inputs, BOOLEAN | bool | Crystools CSwitchBooleanLatent / CSwitchBooleanMask | Lazy; typed |
| N ANY inputs, INT selector (3-20) | index | easy anythingIndexSwitch (up to 20) | Only easy-use scales past 2 inputs |
| N IMAGE / TEXT / CONDITIONING, INT | index | easy imageIndexSwitch / easy textIndexSwitch / easy conditioningIndexSwitch | Typed N-way |
| K ANY inputs, "first non-None wins" | any | rgthree Any Switch | Pick the first connected/non-empty input |
| 1 ANY input → 2 ANY outputs (demux) | bool | Crystools CSwitchFromAny | Unique: output-side mux. Bool routes the one input to one of two outputs |
| 2 BOOLEAN inputs that disagree | logic | easy compare or ImpactCompare then a switch above | Predicate formation lives in comfy-conditionals |
| Toggle entire LoRA stack on/off | bool | rgthree Power Lora Loader with toggles per row | Single node holds the stack + per-LoRA enable/strength |
| Mute/bypass a whole group of nodes | mouse | rgthree fast groups muter (frontend) | Right-click group → Mute / Bypass. No node needed |
CSwitchFromAny only): 1 input → 2
outputs. The bool picks which output port receives the value; the
other port emits None / a default. Use this when one upstream
feeds two divergent downstream paths and you want to send it to only
one at a time.Lazy switches mark unselected branches as "do not evaluate", so the upstream chain feeding the discarded branch is skipped entirely. Saves GPU and time. Eager switches force every upstream branch to compute even if its output gets thrown away.
| Lazy (skip unselected upstream) | Eager (run all branches always) |
|---|---|
easy ifElse, easy imageSwitch, easy textSwitch, easy anythingIndexSwitch (and the typed *IndexSwitch siblings), easy blocker (downstream blocker) | ImpactSwitch / GeneralSwitch (data routing only) |
All CSwitchBoolean* (Crystools) | CSwitchFromAny (must compute input before routing) |
ImpactConditionalBranch, ImpactConditionalBranchSelMode | rgthree Any Switch (selects after upstream resolves) |
When the unselected branch is cheap (a constant or a small VAEDecode), the difference is invisible. When it's a sampler chain, lazy switches save tens of seconds per queue.
cg-use-everywhereThe Anything Everywhere family doesn't have output ports. You wire a
value (model / clip / vae / seed / conditioning / anything) into the
node, and it acts as an invisible producer: any unconnected input
slot of the matching type elsewhere in the graph receives the value
automatically.
| Node | Use when |
|---|---|
Anything Everywhere | One MODEL or VAE is reused by 6 nodes scattered across the graph — declare once, skip 6 reroute wires |
Anything Somewhere | Regex-filtered: broadcasts only to inputs whose socket name matches the regex you set on the broadcaster |
Anything Everywhere Triplet | Positive + negative + latent triplet bundle (the SDXL/Flux conditioning trio) |
Seed Everywhere | Deprecated; the frontend auto-rewrites to a regular Anything Everywhere connected to INT |
Silent-failure mode: if two broadcasters carry compatible types and both could match an empty socket, one of them wins (depends on node id ordering) and the other is silently ignored. Color the broadcasters in the UI so the routing is visible — they're invisible by design and hard to debug otherwise. When debugging, replace with explicit reroutes to see exactly where each value lands.
Use broadcast for scalars and constants (seed, model, vae, a shared prompt). Avoid for transient intermediate values whose meaning shifts as the graph runs — explicit wires there make the workflow more legible.
Both rgthree's Context and easy-use's pipeIn/pipeOut carry a
multi-typed bundle on a single wire. They are not interchangeable.
| rgthree Context | easy-use pipe | |
|---|---|---|
| Wire type | RGTHREE_CONTEXT (custom) | PIPE_LINE (custom) |
| Field access | Named (model / clip / vae / positive / negative / latent / image / seed) | Positional (model, pos, neg, latent, vae, clip, image, seed) |
| Override / edit mid-graph | Context Merge / Context Merge Big | pipeEdit |
| Unpack | Context Switch selects between multiple full contexts; individual fields auto-emerge from the Context node's right side | pipeOut emits all 8 slots; or downstream nodes consume PIPE_LINE directly |
| Bridge between | Convert manually: unpack with Context outputs → repack with pipeIn (and vice-versa) | Same, reverse |
| Best for | Sharing a stable model/clip/vae across many subgraphs | easy-use's own ecosystem (its samplers and pre-samplers expect PIPE_LINE) |
Mixing the two in one workflow is allowed but every cross-bridge is a manual repack. Pick one bundle convention per workflow.
Easy-use ships the only general-purpose loop primitives in this install. Use sparingly — ComfyUI's execution model wasn't designed for iteration, and loops expand at prompt-queue time to a sequence of copied subgraph nodes (so an N=50 loop is N=50 sampler instances in the graph, not one node looping).
| Loop | Setup |
|---|---|
easy forLoopStart → body → easy forLoopEnd | total count (INT), values_1..N carry state through iterations |
easy whileLoopStart → body → easy whileLoopEnd | condition (BOOLEAN) checked after each iteration; emits FLOW_CONTROL token + state |
Best practice:
whileLoopEnd with no terminating
condition will hang the queue forever.values_*) are how you accumulate — write to
them at the end, read at the start.| Primitive | What it does |
|---|---|
easy blocker | Pass-through; if continue=False returns an ExecutionBlocker sentinel. Any downstream node touching the sentinel is silently skipped. |
ImpactConditionalStopIteration | Inside an Impact iterator (detector → detailer loop), halts the loop when its BOOLEAN input is True. |
ImpactExecutionOrderController | Pins a side-effect node (SaveImage, log, webhook) to run before / after a designated other node. Used when ComfyUI's free reordering picks the wrong sequence. |
ExecutionBlocker is the canonical "kill this path" primitive in
ComfyUI — see comfy-conditionals for predicate formation and
detailed semantics (Preview Bridge consumes the sentinel silently;
SaveImage downstream is the abort target).
You have 3–8 LoRAs stacked into a chain. You want each one individually toggleable, with a master "all off" too.
UNETLoader ─┐
│
▼
rgthree Power Lora Loader ← per-row: enabled (bool), name, strength
│
▼
ModelSamplingAuraFlow (or whatever)
CSwitchBooleanAny: bool=on → goes through LoraLoaderModelOnly,
bool=off → bypasses straight to the next stage.User sometimes wants a 2× upscale, sometimes doesn't. Without lazy evaluation, the upscale chain (model loader + KSampler + VAEDecode) runs even when discarded.
┌── on_true: UpscaleModelLoader → Sampler → VAEDecode ──┐
SaveImage upstream ────────── ┤ ├── SaveImage
└── on_false: passthrough ─────────────────────────────┘
▲
│
Crystools CSwitchBooleanImage (lazy)
PrimitiveBoolean, a RgthreeContext field, or
an easy compare predicate.When sharing a workflow that uses Anything Everywhere, the rest of
the graph has unconnected input sockets that "look" wrong but work
fine because of the broadcaster. For readability when sending the
workflow to someone:
Anything Everywhere → "Show connections" (frontend
flag in the rgthree side panel) — renders dashed lines.Reverse the process when receiving a wired workflow you want to clean up.
ComfySwitchNode (core) is widget-overridden by an input.
When you wire a BOOLEAN into the switch slot of ComfySwitchNode,
the node's own widget value is ignored — the connected input wins.
This bites you when the widget shows False but a connected
PrimitiveBoolean(True) is in effect.Any Switch (rgthree) is eager — it evaluates all upstream
inputs before picking the first non-None. Don't use it as a
performance optimizer; use a typed CSwitchBoolean* for laziness.Preview Bridge swallows ExecutionBlocker: if you tee a path
through Preview Bridge to inspect it, and the path is blocked, the
Preview shows nothing and the downstream abort doesn't propagate
through the bridge. Use FastPreview (comfyui-kjnodes) downstream
of a Preview Bridge when blockers may appear, or wire previews off
branches that can't be blocked.ImpactConditionalBranch.cond is BOOLEAN, not INT/FLOAT.
SimpleMathCondition (essentials) returns FLOAT — convert with a
comparator before feeding the branch.IMAGE to a Context Big.latent slot the wire is ignored at
evaluation. Hover the Context outputs to check what's actually
populated.comfy-conditionals — forming the boolean / index that feeds these
switches. Predicates, comparisons, null checks, ExecutionBlocker
patterns.comfy-prompting — Power Lora Loader plays nicely with LoRA
trigger-word autoload nodes; see the cross-ref there for the full
recipe.comfy-debug-preview — Preview Bridge details, FastPreview as the
blocker-aware alternative.comfy-math-strings — primitive sources (PrimitiveBoolean, INT/FLOAT
constants, sliders) that drive these switches.comfy-conditionals.comfy-workflow-layout and
rgthree's UI affordances.wan, z-image,
hidream-o1 skills.CLAUDE.md topic under
"Editing workflow JSON".npx claudepluginhub laurigates/claude-plugins --plugin comfyui-pluginComfyUI predicate/boolean nodes: compare, AND/OR/XOR/NOT, ternary, null/empty/type probes, ExecutionBlocker. Use when forming the boolean that drives a workflow switch or blocker.
Implements advanced ComfyUI node patterns: MatchType for generic type connections, Autogrow for dynamic inputs, MultiType for multiple types, and node expansion. Use for complex, type-safe nodes.
Details ComfyUI API workflow JSON format, node connections, class types, and tools like analyze_workflow for inspecting, loading, and saving workflows.