Overview
Subgraphs let users group nodes into reusable, nestable components. Each subgraph is its ownLGraph with a UUID. For the user-facing guide, see Subgraphs. For backend expansion, see Node Expansion.
Node Identifiers
ComfyUI uses three distinct node identifier types. Using the wrong one causes silent failures.| Type | Format | Used for |
|---|---|---|
node.id | 42 (number) | Local to its immediate graph level. graph.getNodeById(id) |
| Execution ID | "1:2:3" (colon-separated string) | Backend progress messages, UNIQUE_ID |
| Locator ID | "<uuid>:<localId>" or "<localId>" | UI state: badges, errors, images |
Traversing Nodes
Current layer only
All nodes recursively
To walk into nested subgraphs, use a simple recursive helper:Root vs Active Graph
| You want to… | Use |
|---|---|
| Operate on all nodes in the workflow | app.graph (root) |
| Operate on only the visible layer | app.canvas?.graph |
| Access a specific subgraph | someNode.subgraph |
Events
Subgraph-level events
Dispatched onsubgraph.events:
| Event | Payload | When |
|---|---|---|
widget-promoted | { widget, subgraphNode } | Widget promoted to parent node |
widget-demoted | { widget, subgraphNode } | Widget removed from parent node |
input-added | { input } | Input slot added |
removing-input | { input, index } | Input slot being removed |
output-added | { output } | Output slot added |
removing-output | { output, index } | Output slot being removed |
renaming-input | { input, index, oldName, newName } | Input slot renamed |
renaming-output | { output, index, oldName, newName } | Output slot renamed |
Canvas-level events
Dispatched onapp.canvas.canvas (the HTML canvas element):
| Event | Payload | When |
|---|---|---|
subgraph-opened | { subgraph, closingGraph, fromNode } | User navigates into a subgraph |
subgraph-converted | { subgraphNode } | Selection converted to a subgraph |
Listening pattern
Widget Promotion
When aSubgraphInput connects to a widget inside a subgraph, a copy of that widget appears on the parent subgraph node. This fires widget-promoted. Removing the connection fires widget-demoted.
Cleanup
Use anAbortController to clean up all event listeners when a node is removed.
Known Limitations
- Nodes cannot discover their own execution or locator ID from within a subgraph (#8137)
- Widget promotion behavior is still evolving and may change
- Linked (multi-instance) subgraph editing has known issues (#6639)