Skip to main content
Slots and links are exposed through stable handles and frozen snapshots. Use them instead of node.inputs, node.outputs, input.link, output.links, or mutable link records from LiteGraph.

Slot identity and references

A slot index is a position and changes when the slot list changes. A SlotId is stable for the lifetime of the slot. Methods accepting SlotRef support:
A bare number is deliberately not accepted. Use { index } so a volatile positional dependency is visible in code review and search. String resolution is:
  1. exact SlotId;
  2. exact slot name;
  3. while named slots are unavailable, a canonical integer string such as '0' resolves positionally;
  4. no match.
get(name) throws ComfyAmbiguousSlotError when more than one slot has that name. byName(name) returns undefined on ambiguity. Output names may legitimately repeat, so the API never guesses. Slot IDs are runtime identity. Workflows still serialize link endpoints by index, so do not persist a SlotId across save and reload.

Collections

Every node has input and output collections:
The returned arrays are frozen snapshots. Collections are iterable and their handles remain operation-oriented.

Inspecting an input

Important input reads: Use source() to edit physical topology. Use resolvedSource() to understand what execution ultimately receives through reroutes, Get/Set nodes, and other frontend resolvers.

Inspecting an output

links() and targets() are snapshots, so it is safe to iterate while disconnecting.

Connecting and disconnecting

connectTo() returns the new LinkInfo, or undefined when the endpoint does not exist or the host rejects the connection. Normal compatibility and definition hooks still apply. Do not update LinkInfo; it is a record of one observation. Perform the edit through the slot handles.

Adding and removing dynamic slots

SlotOptions supports:
  • shape: 'default', 'optional', 'list', or 'directional';
  • localizedName;
  • a custom graph-space position and link direction;
  • widget, naming the widget whose socket form this input represents;
  • widgetConfig, the declaration a connected Primitive should render.
Shapes, localized names, positions, directions, colors, and widget-input metadata can affect saved workflow bytes. Reproduce the original declaration when wire compatibility matters. Removing a slot disconnects its links.

Reordering slots safely

The names must be a complete permutation of the current slots. The host updates every affected link endpoint as part of the operation and preserves link IDs. Permuting an internal slot array directly would silently retarget connections, because serialized links store endpoint indexes. The slot order itself is serialized, so reordering changes the workflow by design while preserving which logical slots its links reach.

Modifying a slot

Apply related changes atomically:
SlotPatch supports name, label, localized name, type, position, direction, connected and unconnected colors, and shape. InputSlotPatch additionally supports widget identity and widget configuration. A type may be a string or an array of accepted types. The host normalizes an array to the comma-separated form used by its compatibility checks. Retyping keeps existing links. Dynamic wildcard-to-concrete nodes depend on that behavior; explicitly disconnect a link when the feature requires it.
moveLinksTo() moves every link to another output on the same node and preserves link IDs. Disconnecting and reconnecting would allocate new IDs and change the serialized workflow. The move deliberately does not revalidate types. The observed migration pattern moves links away and then retypes a slot; checking compatibility halfway through would reject that valid sequence.

Widget-backed inputs

A dynamic input that is the socket form of a widget must carry the relationship:
This is not cosmetic. Widget-backed inputs serialize differently from ordinary sockets, and the widget keeps its position in widgets_values. InputSlotHandle.modify({ widget, widgetConfig }) updates an existing input. Use null for widget to clear the relationship.

Physical and resolved topology

Frontend-only nodes can forward, replace, or omit execution values without changing physical links. Keep the distinction explicit:
An executable source is one of:
  • { kind: 'output', graphId, nodeId, outputIndex };
  • { kind: 'literal', value };
  • { kind: 'omitted', reason }.
Resolution is read-only and scoped to the input’s graph. See Execution and resolution for defining resolvers and suppliers.