NodeHandle to work with
one node that already belongs to a graph.
Reading definitions
NodeDef is frozen metadata:
inputs[].options and hidden deliberately preserve pack-owned backend data.
They are declarations, not live widget values or hidden-input execution values.
Use defs.all() to take a snapshot of every definition and defs.has(type) for
an existence check. defs.refresh() asks the backend to reload definitions;
defs.onRefreshed() observes completion.
Extending definitions
Builder configuration
Structural changes to a live node (dynamic slots, values, ordering, or
connections) belong on the instance handles supplied by lifecycle callbacks.
Lifecycle and behavior hooks
onBeforeConnect returns false to veto. onUnplacedLink returns true after
the callback wires the link itself. onDragOver returns true to route the
drop; onDrop returns true to claim it.
onSerialize must return deterministic, synchronous, pack-owned data. Its data
comes back through onConfigured. Do not return core workflow fields or mutate
a serialization object supplied by the host.
Defining a frontend-owned node
NodeDefinition is plain data, not a class. It supports inputs, outputs,
widgets, frontend execution, supply, and the common lifecycle callbacks.
For builder-only behavior such as menu entries, preview frames, resize, hover,
double-click, connect veto, or unplaced links, define the type and extend the
same type separately.
Working with a live node
Node handles can come from lifecycle callbacks, graph lookups, selection, groups, execution events, or subgraph scopes.Identity and presentation
idis identity inside the owning graph.graphIdidentifies that graph.typeis immutable definition identity.comfyClassis the backend class identifier when it differs fromtype.- title, mode, collapsed state, pinned state, colors, and shape use explicit getter/setter pairs.
type. Use comfy.graph.replace(node.id, newType) to rebuild the
node and preserve compatible state and links.
Properties
UsegetProperty, getProperties, and setProperty. getProperties() returns
an inert object rather than a mutable reference.
onPropertyChanged can normalize or reject a user edit:
setValue() replaces the pending property value without re-entering the
property callback. reject() restores the previous value.
Geometry
Do not reconstruct title height, slot spacing, pan, zoom, or device-pixel-ratio
math from renderer constants.
Output images
getOutputImages() returns URLs for the images or previews the node currently
exposes. It never returns renderer-owned HTMLImageElement objects.
getDisplayedImageIndex() identifies the image selected or hovered by the user,
or returns undefined when there is no such choice.
Collections and snapshots
Each node exposes:node.snapshot() returns a frozen NodeSnapshot with identity, presentation,
position, and size. It can return undefined when the entity is gone.
Menus and badges
Node menu entries are declarative and host-rendered:items, either a fixed array or a
function of the current node. A submenu parent omits run.
Badges are small labels rendered in node chrome under both renderers:
Pack-owned instance state
Do not add fields to a node or handle. Keep state outside the entity and include graph scope in the key:comfy.sameEntity() rather than ===.