Combo Dynamic (cozy)
The two-file lesson in how ComfyUI dropdowns actually talk to each other
- OPTIONS
Let's be honest about what this is up front: Combo Dynamic (cozy) is not a tool you keep in your workflow. It's an example, and the pack is up-front about it - the node's category is literally _EXAMPLES. What it is, is the cleanest two-file demonstration you'll find of how one ComfyUI node can reach into another node's dropdown widget and keep their selections in sync. If you've ever wondered how packs like the ones that "mirror a remote combobox" do it, or you're writing your own custom node and keep fighting the combo widget, this is the shortest path to getting it.
The backstory matters here: the pack comes from the same author as Jovimetrix, and the README says it exists because people ask the same "how do I feed one dropdown from another" question over and over - and the answers always live buried inside some big compound pack where you have to unwind fifty files to find the part that matters. This one is kept to two files: one Python entry point and one JavaScript file. That's the whole point.
How it works
The magic isn't in the Python at all - ComboDynamicNodeCozy is a deliberately empty shell with no FUNCTION doing real work. All the behavior lives in web/combonode.js, a ComfyUI frontend extension that hooks into three node lifecycle events:
- When you connect the
OPTIONSoutput into another node's combo-input socket, it grabs that remote widget's value list, fills the localcombodropdown with it, and copies the remote's current selection across. - A
callbackon the local dropdown writes your pick straight back to the remote widget, so they stay in lockstep either direction. - The
textfield dumps the whole remote value list as plain text - handy for seeing exactly what the connected node is offering. - When you disconnect, it clears both the local list and the text and forgets the remote.
So the wire goes: you pick the remote node's combo socket, this node adopts its values, and editing either side updates the other. Great pattern to copy.
The inputs and outputs that matter
combo(enum, optional) - the dropdown that mirrors the connected remote. You don't type into it; the connection populates it.text(STRING, multiline, optional) - the readout of the remote's full value list.OPTIONSoutput (typeCOMBO) - this is the socket you wire into the other node's combo input to kick the whole mirror off. Per the tooltip, "plug into an existing Combobox widget to grab its values."
Nothing here runs a model, and there's nothing heavy anywhere in the pack: requirements.txt is empty and the project declares zero dependencies.
Installing it
Clone it into custom_nodes and restart ComfyUI:
cd ComfyUI/custom_nodes
git clone https://github.com/cozy-comfyui/cozy_combo_dynamic
Or find "Cozy Combo Dynamic" (or cozy_combo_dynamic) in ComfyUI Manager. No model files, no pip installs, no extra requirements. After restart, hard-refresh the browser tab so the JS extension actually loads - forgetting that is the classic "node appears but does nothing" moment.
Where people trip over it
The one real footgun is in the code: the local dropdown's callback is registered immediately, but it only writes to the remote after you've connected something. Touch the combo dropdown before any connection exists and the JS hits a null combo_remote and throws. Connect first, then play.
Also worth knowing before you base your own node on this: it's written against the classic frontend widget API. ComfyUI's Nodes 2.0 frontend rewrite has been churning how widgets and extension hooks work, so if you copy this pattern today, sanity-check it on your ComfyUI version rather than assuming it still behaves identically. For learning the mechanism, though, you won't find a cleaner reference.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| comboopt | COMBO | 0 options: | |
| textopt | STRING | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| OPTIONS | COMBO | Plug into an existing Combobox widget to grab it's values |