Importing the API
/comfy/api/v2.js re-exports that instance rather than constructing a
new registry.
Extension modules should import comfy so the dependency is explicit, the
published contract is clear, and tooling can understand it. Do not make a
global object part of your pack’s runtime contract.
These legacy globals and modules are not part of this contract:
window.comfyAPI;window.app;/scripts/app.js,/scripts/api.js,/scripts/widgets.js;LiteGraphand renderer globals.
Versioning and capability probes
supports() for optional behavior and require() for a feature without
which the extension cannot work. Do not compare application versions, parse
comfy.version, or probe an internal member.
comfy.capabilities() returns a frozen list of everything the host provides.
comfy.forMajor(major) pins a public major when a pack deliberately maintains
more than one implementation.
Registration at module load
The API is ready for declarations before the graph has completed setup. These operations normally belong at module scope:Extending backend node definitions
defs.extend(selector, apply) is the replacement for
beforeRegisterNodeDef and prototype patching:
- an exact type string;
- an array of type strings;
- a type-name regular expression;
{ category: string | RegExp };- a predicate over
NodeDefwhen the other forms cannot express the match.
def is the frozen definition after earlier extensions have run.
Registered callbacks compose; there is no previous prototype callback to
capture or invoke.
Defining a frontend-owned node type
Use plain data rather than subclassingLGraphNode:
type must be globally unique. define() returns an unregister function.
execution: 'frontend' keeps the node out of the backend prompt. A resolver is
optional: without one, the node is simply omitted. See
Execution and resolution before defining execution behavior.
Defining an input widget type
defineWidgetType() replaces getCustomWidgets for a Python input type:
WidgetTypeContext,
not a node handle. Use context.onNodeReady() when behavior genuinely needs the
owning NodeHandle.
The element belongs to the pack’s mounted UI surface; it is not a supported way to change ComfyUI’s host page. Use the supplied container and published UI contributions instead of querying or changing host-owned page elements.
Lifecycle signals
Application ready
Workflow loaded
Definition lifecycle
UseNodeDefBuilder or NodeDefinition callbacks for individual instances:
onCreatedafter the node joins a graph;onConfiguredafter saved data is applied;onRemovedwhen it leaves;onExecutedandonPreviewfor backend results;onConnectionsChanged,onResized,onHover,onDoubleClick,onPropertyChanged,onDragOver, andonDropfor semantic editor behavior.
NodeCreatedEvent.restored distinguishes fresh nodes from nodes carrying saved
state. NodeCreatedEvent.loading distinguishes workflow load from paste or
duplication.
Cleanup and ownership
Registrations and subscriptions commonly returnUnsubscribe:
- module registrations may live for the page;
- a sidebar tab or dialog releases listeners, observers, and timers from its
destroycallback; - a mounted widget releases them from
MountDef.destroyor the function returned by a widget type’srender; - per-node state should be removed from
onRemoved.