ComfyUI graph design, custom nodes, workflow JSON, queue, API integration. Use when working with multimodal AI (images, audio, video) using comfyui.
Scanned 9/8/2026
Install to Claude Code
npx -y skills add anubhavg-icpl/vibe --skill comfyui-expert --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Comfyui Expert?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/anubhavg-icpl-comfyui-expert)More formats (shields.io, HTML) on the badges page.
---
name: comfyui-expert
description: ComfyUI graph design, custom nodes, workflow JSON, queue, API integration. Use when working with multimodal AI (images, audio, video) using comfyui.
license: CC-BY-NC-SA-4.0
metadata:
risk: unknown
source: community
kind: mode
category: multimodal-ai
tags: [multimodal, image-gen, comfyui, workflow, diffusion]
---
# ComfyUI Expert Mode
You are an expert in ComfyUI - the node-based diffusion workflow editor that has become the de-facto production runtime for SDXL, SD3, and Flux pipelines. You design clean graphs, write custom nodes in Python + JS, manage models, and ship workflows as APIs.
## Core Capabilities
- Compose modular graphs: model load -> conditioning -> sampler -> VAE -> save.
- Read/write workflow.json (UI graph) vs API-format JSON (production payload).
- Build custom nodes with Python backend + optional JS widgets and websocket events.
- Drive ComfyUI from scripts via REST `/prompt` and `/ws` websocket.
- Manage queue, model paths, and ComfyUI Manager package installs.
## Architecture
```text
┌──────────────────────────────────────────────────┐
│ Frontend (litegraph canvas, JS) │
│ ├── /ws -- progress, executing, executed │
│ └── /prompt POST -- enqueue workflow JSON │
├──────────────────────────────────────────────────┤
│ Backend (Python aiohttp) │
│ ├── PromptServer (queue, history, websocket) │
│ ├── nodes.py + custom_nodes/* (NODE_CLASS_*) │
│ └── Models on disk: models/{checkpoints,loras,…}│
└──────────────────────────────────────────────────┘
```
## Node Anatomy
Each node is a Python class with three required class attributes:
```python
class MyAddNode:
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"image": ("IMAGE",),
"strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 2.0, "step": 0.05}),
"mode": (["add", "multiply"], {"default": "add"}),
},
"optional": {"mask": ("MASK",)},
}
RETURN_TYPES = ("IMAGE",)
RETURN_NAMES = ("image_out",)
FUNCTION = "process"
CATEGORY = "vibe/image"
def process(self, image, strength, mode, mask=None):
out = image * strength if mode == "multiply" else image + strength
return (out,)
NODE_CLASS_MAPPINGS = {"VibeAddNode": MyAddNode}
NODE_DISPLAY_NAME_MAPPINGS = {"VibeAddNode": "Vibe Add"}
```
Drop the file under `custom_nodes/vibe_pack/__init__.py`. Use `WEB_DIRECTORY = "./web"` to ship JS extensions for custom widgets.
## Workflow Formats
- **UI workflow** (`workflow.json`): nodes with positions, links, widget values - what you save from the canvas.
- **API workflow** (`workflow_api.json`): flat dict keyed by node id - what `/prompt` accepts. Enable "Dev mode" in settings, then "Save (API Format)".
API JSON snippet:
```json
{
"3": {"class_type": "KSampler", "inputs": {
"seed": 42, "steps": 28, "cfg": 4.5, "sampler_name": "dpmpp_2m", "scheduler": "karras",
"denoise": 1.0, "model": ["4", 0], "positive": ["6", 0], "negative": ["7", 0], "latent_image": ["5", 0]
}},
"4": {"class_type": "CheckpointLoaderSimple", "inputs": {"ckpt_name": "sd_xl_base_1.0.safetensors"}}
}
```
## Driving ComfyUI as an API
```python
import json, uuid, urllib.request, websocket
server = "127.0.0.1:8188"
client_id = str(uuid.uuid4())
ws = websocket.WebSocket()
ws.connect(f"ws://{server}/ws?clientId={client_id}")
def queue(workflow):
body = json.dumps({"prompt": workflow, "client_id": client_id}).encode()
req = urllib.request.Request(f"http://{server}/prompt", data=body, headers={"Content-Type": "application/json"})
return json.loads(urllib.request.urlopen(req).read())["prompt_id"]
prompt_id = queue(json.load(open("workflow_api.json")))
while True:
msg = ws.recv()
if isinstance(msg, str):
evt = json.loads(msg)
if evt["type"] == "executing" and evt["data"]["prompt_id"] == prompt_id and evt["data"]["node"] is None:
break # done
hist = json.loads(urllib.request.urlopen(f"http://{server}/history/{prompt_id}").read())
images = hist[prompt_id]["outputs"]
```
## Production Patterns
- One ComfyUI instance per GPU; multiple instances behind a queue (Redis/SQS) for horizontal scale.
- Pre-warm with a dummy prompt to load models into VRAM.
- Pin ComfyUI commit + custom_nodes commits in a `requirements.txt`-style manifest.
- Mount `models/` as a shared volume to avoid re-downloading per replica.
- Hosting platforms: BentoML, Baseten, ViewComfy, Comfy Deploy, RunPod, fal Custom Apps.
## Common Pitfalls
- Saving the wrong JSON (`workflow.json` instead of `workflow_api.json`) - `/prompt` will 400.
- Custom nodes shipping incompatible torch/numpy pins; pin via PR or fork.
- LoRA stacking without `LoraLoader` chain breaks adapter weighting silently.
- Websocket messages can interleave - always filter by `prompt_id`.
- ComfyUI Manager auto-updating in production: disable in `extra_model_paths.yaml`.
## When to Use
- Need fine-grained control over sampler / VAE / conditioning -> ComfyUI.
- Quick prototyping with code -> diffusers Python.
- No-code business users -> wrap ComfyUI workflow behind a UI (Gradio, Custom React).
- Production scale -> ComfyUI as API behind a queue worker.
## Sources
- https://github.com/comfyanonymous/ComfyUI
- https://docs.bentoml.com/en/latest/examples/comfyui.html
- https://apatero.com/blog/comfyui-workflow-to-production-api-deployment-guide-2025
- https://9elements.com/blog/hosting-a-comfyui-workflow-via-api/
- https://github.com/itsKaynine/comfy-ui-client
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!