comfyui-node-basics
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseComfyUI Custom Node Basics (V3 API)
ComfyUI自定义节点基础(V3 API)
ComfyUI uses Python classes to define nodes. The V3 API is the current recommended approach. Nodes inherit from and define a schema + execute method.
io.ComfyNodeComfyUI使用Python类定义节点,V3 API是当前官方推荐的实现方式。节点继承自,需定义schema和execute方法。
io.ComfyNodeQuick Start
快速开始
python
from comfy_api.latest import ComfyExtension, io
class MyNode(io.ComfyNode):
@classmethod
def define_schema(cls):
return io.Schema(
node_id="MyNode",
display_name="My Custom Node",
category="my_category",
inputs=[
io.Image.Input("image"),
io.Float.Input("strength", default=1.0, min=0.0, max=1.0, step=0.01),
],
outputs=[
io.Image.Output("IMAGE"),
],
)
@classmethod
def execute(cls, image, strength):
result = image * strength
return io.NodeOutput(result)python
from comfy_api.latest import ComfyExtension, io
class MyNode(io.ComfyNode):
@classmethod
def define_schema(cls):
return io.Schema(
node_id="MyNode",
display_name="My Custom Node",
category="my_category",
inputs=[
io.Image.Input("image"),
io.Float.Input("strength", default=1.0, min=0.0, max=1.0, step=0.01),
],
outputs=[
io.Image.Output("IMAGE"),
],
)
@classmethod
def execute(cls, image, strength):
result = image * strength
return io.NodeOutput(result)V3 Node Class Structure
V3节点类结构
Every V3 node requires:
- Inherit from
io.ComfyNode - - classmethod returning
define_schema(cls)io.Schema - - classmethod performing the computation
execute(cls, ...)
python
from typing_extensions import override
from comfy_api.latest import ComfyExtension, io
class ImageBrighten(io.ComfyNode):
@classmethod
def define_schema(cls):
return io.Schema(
node_id="ImageBrighten", # unique identifier
display_name="Brighten Image", # shown in UI
category="image/adjust", # menu path
description="Adjusts image brightness",
inputs=[
io.Image.Input("image"),
io.Float.Input("factor", default=1.2, min=0.0, max=3.0, step=0.1),
],
outputs=[
io.Image.Output("IMAGE"),
],
)
@classmethod
def execute(cls, image, factor):
result = torch.clamp(image * factor, 0.0, 1.0)
return io.NodeOutput(result)所有V3节点都需要包含以下部分:
- 继承自
io.ComfyNode - - 类方法,返回
define_schema(cls)对象io.Schema - - 类方法,执行节点的计算逻辑
execute(cls, ...)
python
from typing_extensions import override
from comfy_api.latest import ComfyExtension, io
class ImageBrighten(io.ComfyNode):
@classmethod
def define_schema(cls):
return io.Schema(
node_id="ImageBrighten", # 唯一标识符
display_name="Brighten Image", # UI上展示的名称
category="image/adjust", # 菜单路径
description="Adjusts image brightness",
inputs=[
io.Image.Input("image"),
io.Float.Input("factor", default=1.2, min=0.0, max=3.0, step=0.1),
],
outputs=[
io.Image.Output("IMAGE"),
],
)
@classmethod
def execute(cls, image, factor):
result = torch.clamp(image * factor, 0.0, 1.0)
return io.NodeOutput(result)io.Schema Fields
io.Schema字段说明
python
io.Schema(
node_id="UniqueNodeID", # required: unique string ID
display_name="Display Name", # optional: shown in UI menus
category="category/subcategory", # menu hierarchy (default "sd")
description="Node description", # optional: tooltip text
inputs=[...], # list of Input objects
outputs=[...], # list of Output objects
hidden=[...], # list of Hidden enum values
is_output_node=False, # True for nodes with side effects (save, preview)
is_experimental=False, # marks as experimental
is_deprecated=False, # marks as deprecated
is_dev_only=False, # hidden unless dev mode enabled
is_api_node=False, # marks as API-only node
is_input_list=False, # receive full lists instead of individual items
not_idempotent=False, # prevents caching
accept_all_inputs=False, # accept arbitrary inputs via **kwargs
enable_expand=False, # allow node expansion (subgraphs)
search_aliases=["alias1", "alias2"],# alternative search terms
essentials_category="Basic", # optional: Essentials tab category
price_badge=None, # optional: PriceBadge for API nodes
)python
io.Schema(
node_id="UniqueNodeID", # 必填:全局唯一的字符串ID
display_name="Display Name", # 可选:UI菜单中展示的名称
category="category/subcategory", # 菜单层级(默认"sd")
description="Node description", # 可选:悬停提示文本
inputs=[...], # Input对象列表
outputs=[...], # Output对象列表
hidden=[...], # Hidden枚举值列表
is_output_node=False, # 有副作用的节点设为True(保存、预览类节点)
is_experimental=False, # 标记为实验性功能
is_deprecated=False, # 标记为已废弃
is_dev_only=False, # 仅开发模式下可见
is_api_node=False, # 标记为仅API可用的节点
is_input_list=False, # 接收完整列表而非单个条目
not_idempotent=False, # 禁用缓存
accept_all_inputs=False, # 通过**kwargs接收任意输入
enable_expand=False, # 允许节点展开(子图)
search_aliases=["alias1", "alias2"],# 搜索别名
essentials_category="Basic", # 可选: Essentials标签页分类
price_badge=None, # 可选:API节点的价格标识
)V3 Node Registration
V3节点注册
V3 nodes are registered via and :
ComfyExtensioncomfy_entrypoint()python
from typing_extensions import override
from comfy_api.latest import ComfyExtension, io
class MyNode(io.ComfyNode):
@classmethod
def define_schema(cls):
return io.Schema(
node_id="MyNode",
display_name="My Node",
category="my_nodes",
inputs=[io.String.Input("text", multiline=True)],
outputs=[io.String.Output()],
)
@classmethod
def execute(cls, text):
return io.NodeOutput(text.upper())
class MyExtension(ComfyExtension):
@override
async def get_node_list(self) -> list[type[io.ComfyNode]]:
return [MyNode]
async def comfy_entrypoint() -> MyExtension:
return MyExtension()The function must be defined at the module level (in the file directly imported by ComfyUI).
comfy_entrypoint()V3节点通过和注册:
ComfyExtensioncomfy_entrypoint()python
from typing_extensions import override
from comfy_api.latest import ComfyExtension, io
class MyNode(io.ComfyNode):
@classmethod
def define_schema(cls):
return io.Schema(
node_id="MyNode",
display_name="My Node",
category="my_nodes",
inputs=[io.String.Input("text", multiline=True)],
outputs=[io.String.Output()],
)
@classmethod
def execute(cls, text):
return io.NodeOutput(text.upper())
class MyExtension(ComfyExtension):
@override
async def get_node_list(self) -> list[type[io.ComfyNode]]:
return [MyNode]
async def comfy_entrypoint() -> MyExtension:
return MyExtension()comfy_entrypoint()V1 Node Structure (Legacy Reference)
V1节点结构(旧版参考)
V1 nodes use class attributes and :
NODE_CLASS_MAPPINGSpython
class MyNodeV1:
CATEGORY = "my_category"
FUNCTION = "execute"
RETURN_TYPES = ("IMAGE",)
RETURN_NAMES = ("image",)
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"image": ("IMAGE",),
"strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0}),
}
}
def execute(self, image, strength):
return (image * strength,)
NODE_CLASS_MAPPINGS = {"MyNodeV1": MyNodeV1}
NODE_DISPLAY_NAME_MAPPINGS = {"MyNodeV1": "My Node V1"}V1节点使用类属性和注册:
NODE_CLASS_MAPPINGSpython
class MyNodeV1:
CATEGORY = "my_category"
FUNCTION = "execute"
RETURN_TYPES = ("IMAGE",)
RETURN_NAMES = ("image",)
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"image": ("IMAGE",),
"strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0}),
}
}
def execute(self, image, strength):
return (image * strength,)
NODE_CLASS_MAPPINGS = {"MyNodeV1": MyNodeV1}
NODE_DISPLAY_NAME_MAPPINGS = {"MyNodeV1": "My Node V1"}Key Differences: V3 vs V1
核心差异:V3 vs V1
| Aspect | V3 | V1 |
|---|---|---|
| Base class | | Plain class |
| Execute method | | Instance method (custom name via |
| Inputs | | |
| Outputs | | |
| Return value | | Plain tuple |
| Registration | | |
| State | No instance state (classmethods) | Instance state allowed |
| Hidden inputs | | kwargs from |
| 对比项 | V3 | V1 |
|---|---|---|
| 基类 | | 普通类 |
| 执行方法 | | 实例方法(通过 |
| 输入定义 | | |
| 输出定义 | | |
| 返回值 | | 普通元组 |
| 注册方式 | | |
| 状态管理 | 无实例状态(全类方法) | 允许使用实例状态 |
| 隐藏输入 | | 来自 |
Important Rules
重要规则
- must be globally unique across all nodes
node_id - parameters must match input IDs exactly
execute() - All methods are in V3 (no instance state)
@classmethod - Return matching output count
io.NodeOutput(val1, val2, ...) - Category uses separator for hierarchy:
/"image/transform" - Prefix category with to hide from menus:
_"_for_testing"
- 必须在所有节点中全局唯一
node_id - 的参数必须和输入ID完全匹配
execute() - V3中所有方法都是(无实例状态)
@classmethod - 返回的参数数量需和输出数量匹配
io.NodeOutput(val1, val2, ...) - 分类使用分隔层级:
/"image/transform" - 分类前缀加可在菜单中隐藏:
_"_for_testing"
See Also
参考资料
- - Data types (IMAGE, LATENT, MASK, etc.)
comfyui-node-datatypes - - Input configuration details
comfyui-node-inputs - - Output types and UI outputs
comfyui-node-outputs - - Project structure and packaging
comfyui-node-packaging - - Execution lifecycle and caching
comfyui-node-lifecycle
- - 数据类型(IMAGE、LATENT、MASK等)
comfyui-node-datatypes - - 输入配置详情
comfyui-node-inputs - - 输出类型和UI输出
comfyui-node-outputs - - 项目结构和打包
comfyui-node-packaging - - 执行生命周期和缓存
comfyui-node-lifecycle