comfyui-node-advanced
ComfyUI advanced node patterns - MatchType, Autogrow, DynamicCombo, node expansion, MultiType, wildcard inputs, loops. Use when…
ComfyUI node execution lifecycle - caching, fingerprint_inputs/IS_CHANGED, validate_inputs/VALIDATE_INPUTS, check_lazy_status, execution order. Use when debugging execution, implementing caching control, input validation, or understanding execution flow.
Claude Code
$ npx -y skills add jtydhr88/comfyui-custom-node-skills --skill comfyui-node-lifecycle --agent claude-code
Codex
$ npx skills add jtydhr88/comfyui-custom-node-skills --skill comfyui-node-lifecycle -a codex -y
Cursor
$ npx skills add jtydhr88/comfyui-custom-node-skills --skill comfyui-node-lifecycle -a cursor -y
Gemini CLI
$ npx skills add jtydhr88/comfyui-custom-node-skills --skill comfyui-node-lifecycle -a gemini-cli -y
GitHub Copilot
$ npx skills add jtydhr88/comfyui-custom-node-skills --skill comfyui-node-lifecycle -a github-copilot -y
OpenCode
$ npx skills add jtydhr88/comfyui-custom-node-skills --skill comfyui-node-lifecycle -a opencode -y
Windsurf
$ npx skills add jtydhr88/comfyui-custom-node-skills --skill comfyui-node-lifecycle -a windsurf -y
name: comfyui-node-lifecycle description: ComfyUI node execution lifecycle - caching, fingerprint_inputs/IS_CHANGED, validate_inputs/VALIDATE_INPUTS, check_lazy_status, execution order. Use when debugging execution, implementing caching control, input validation, or understanding execution flow.
Understanding the execution lifecycle helps build efficient, correct nodes.
1. Prompt received from frontend 2. Validation phase ├── Look up each node class ├── Call INPUT_TYPES() / define_schema() for input specs ├── Validate connections and types ├── Call validate_inputs() for each node └── Validate loop boundaries (StartLoop/EndLoop pairing, v0.36+) 3. Build execution order (topological sort from output nodes) 4. For each node in order: ├── Cache check (fingerprint_inputs) ├── Input resolution (get upstream values) ├── Lazy evaluation (check_lazy_status) ├── Execute function └── Store outputs in cache 5. Return results to frontend
ComfyUI executes from **output nodes backward**: 1. Identifies output nodes (`is_output_node=True`) 2. Builds dependency graph 3. Topological sort determines execution order 4. Only nodes connected to output nodes execute
Controls when a node re-executes vs uses cached results.
class RandomNode(io.ComfyNode):
@classmethod
def define_schema(cls):
return io.Schema(
node_id="RandomNode",
display_name="Random Value",
category="utils",
inputs=[
io.Float.Input("min_val", default=0.0),
io.Float.Input("max_val", default=1.0),
],
outputs=[io.Float.Output("FLOAT")],
)
@classmethod
def fingerprint_inputs(cls, min_val, max_val):
"""Return value compared to last run. Different value = re-execute."""
# Return unique value each time to always re-execute
import time
return time.time()
@classmethod
def execute(cls, min_val, max_val):
import random
return io.NodeOutput(random.uniform(min_val, max_val))**How caching works**:
**V1 equivalent** (`IS_CHANGED`):
@classmethod
def IS_CHANGED(s, min_val, max_val):
return time.time() # always re-executeFor nodes that should never be cached:
io.Schema(
node_id="AlwaysRunNode",
not_idempotent=True, # prevents cache sharing between instances of the same node
# ...
)> **Important:** `not_idempotent=True` does **not** prevent a node from reusing its own cached output on subsequent runs. It only prevents cache sharing between different instances of the same node type that have identical inputs. To force re-execution every run (e.g., for file-writing nodes), you must also implement `fingerprint_inputs` (V3) or `IS_CHANGED` (V1) returning a unique value each time.
For nodes with interactive UI that produce intermediate outputs (e.g., Image Crop, Painter). These behave like output nodes (UI results are cached and resent to the frontend on page refresh) but do NOT automatically get added to the execution list — they only execute if on the dependency path of a real output node.
io.Schema(
node_id="InteractiveCropNode",
has_intermediate_output=True,
# ...
)Share cached node outputs across ComfyUI instances (e.g. a shared network cache) by registering a `CacheProvider`:
from comfy_api.latest import Caching
class MyCacheProvider(Caching.CacheProvider):
async def on_lookup(self, context): # context: node_id, class_type, cache_key_hash
... # return Caching.CacheValue(outputs=[...], ui={...}) or None on miss
async def on_store(self, context, value):
... # store to external storage (dispatched as a background task)
def should_cache(self, context, value=None) -> bool:
return True # return False to skip external caching for a node
def on_prompt_start(self, prompt_id): ...
def on_prompt_end(self, prompt_id): ...
# Register in ComfyExtension.on_load():
api = ComfyAPI()
await api.caching.register_provider(MyCacheProvider())Providers are consulted on local cache miss, in registration order. Exceptions from providers never break execution.
On a cache hit the cached UI is resent (with `id`/`preview_id` stripped from UI entries — see `comfyui-node-outputs`). For RAM-cache sizing of custom output objects see `_comfy_cache_tensors` in `comfyui-node-datatypes`.
Validates inputs before execution. Runs during the validation phase.
class ValidatedNode(io.ComfyNode):
@classmethod
def define_schema(cls):
return io.Schema(
node_id="ValidatedNode",
display_name="Validated Node",
category="utils",
inputs=[
io.Int.Input("width", default=512, min=1, max=8192),
io.Int.Input("height", default=512, min=1, max=8192),
],
outputs=[io.Image.Output("IMAGE")],
)
@classmethod
def validate_inputs(cls, width, height):
"""Return True if valid, or error string if invalid."""
if width % 8 != 0 or height % 8 != 0:
return "Width and height must be multiples of 8"
if width * height > 4096 * 4096:
return "Total pixels exceed maximum (4096x4096)"
return True
@classmethod
def execute(clsA curated collection of agent skills (for Claude Code and OpenAI Codex) for developing ComfyUI custom nodes. These skills give the agent comprehensive knowledge of the ComfyUI node system, covering both the V3 (recommended) and V1 (legacy) APIs.
ComfyUI advanced node patterns - MatchType, Autogrow, DynamicCombo, node expansion, MultiType, wildcard inputs, loops. Use when…
ComfyUI custom node fundamentals - V3 node structure, Schema, inputs/outputs, registration. Use when creating new ComfyUI custom…
ComfyUI data types - IMAGE, LATENT, MASK, CONDITIONING, MODEL, CLIP, VAE, AUDIO, VIDEO, 3D types, widget types, and custom types.…
ComfyUI frontend JavaScript extensions - hooks, widgets, sidebar tabs, commands, settings, toasts, dialogs. Use when adding UI…
ComfyUI node input types - INT, FLOAT, STRING, BOOLEAN, COMBO widgets, hidden inputs, optional inputs, lazy inputs, force_input.…
ComfyUI V1 to V3 node migration - converting legacy nodes to the V3 API. Use when migrating existing custom nodes from V1 to V3,…
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…
Ask which skill or flow fits your situation. A router over the skills in this repo.