8.4 KiB
Custom Nodes Guide
This document provides detailed information for developers who want to create custom nodes for ComfyUI.
Table of Contents
- Introduction
- Setting Up the Development Environment
- Custom Node Structure
- Creating Your First Node
- Node Inputs and Outputs
- Advanced Node Development
- Distributing Custom Nodes
- Best Practices
Introduction
ComfyUI's power comes from its extensibility through custom nodes. Custom nodes allow you to:
- Add new functionality not available in the core application
- Optimize existing workflows
- Create specialized interfaces for specific tasks
- Integrate with external tools and services
This guide will walk you through creating, testing, and distributing custom nodes.
Setting Up the Development Environment
Prerequisites
- Python 3.9+ (3.11 recommended)
- ComfyUI installed (source installation recommended for development)
- Basic knowledge of Python
- Understanding of ComfyUI's node system
Development Environment Setup
-
Install ComfyUI from source:
git clone https://github.com/comfyanonymous/ComfyUI.git cd ComfyUI # Set up development environment uv venv .venv source .venv/bin/activate # Linux/macOS # or .venv\Scripts\activate # Windows # Install dependencies uv pip install -e ".[dev]" -
Create a custom nodes directory:
mkdir -p custom_nodes/my_custom_node cd custom_nodes/my_custom_node
Custom Node Structure
A typical custom node package has the following structure:
my_custom_node/
├── __init__.py # Entry point for your node
├── nodes.py # Node implementation
├── requirements.txt # Dependencies
├── README.md # Documentation
└── web/ # [Optional] Frontend components
├── js/
│ └── my_node.js # Custom UI components
└── style.css # Custom styling
Creating Your First Node
Basic Node Template
Create a file called nodes.py with the following content:
# nodes.py
import torch
import numpy as np
from PIL import Image
class MyCustomNode:
"""
A simple custom node that applies a filter to an image.
"""
# Define the input and output types for the node
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"image": ("IMAGE",),
"intensity": ("FLOAT", {
"default": 1.0,
"min": 0.0,
"max": 2.0,
"step": 0.01
}),
},
}
# Define the return types
RETURN_TYPES = ("IMAGE",)
# Optional: Define output names (defaults to return types)
RETURN_NAMES = ("filtered_image",)
# Define the node category for UI organization
CATEGORY = "image/filters"
# Optional: Add a description
DESCRIPTION = "Applies a custom filter to the input image"
def __init__(self):
pass
def execute(self, image, intensity):
# Convert from tensor format to numpy for processing
# Assuming image is [B, H, W, C] format
img_np = image.numpy()
# Apply a simple brightness adjustment as an example
adjusted = np.clip(img_np * intensity, 0, 1)
# Convert back to tensor
result = torch.from_numpy(adjusted)
return (result,)
Register Your Node
Create an __init__.py file to register your node:
# __init__.py
from .nodes import MyCustomNode
NODE_CLASS_MAPPINGS = {
"MyCustomNode": MyCustomNode
}
NODE_DISPLAY_NAME_MAPPINGS = {
"MyCustomNode": "My Custom Filter"
}
Node Inputs and Outputs
Input Types
ComfyUI supports several input types:
INT: Integer valuesFLOAT: Floating point valuesSTRING: Text stringsBOOLEAN: True/False valuesIMAGE: Image data- Custom enum types: A list of string options
Input Configuration
For numeric inputs, you can provide additional configuration:
"parameter_name": ("FLOAT", {
"default": 1.0,
"min": 0.0,
"max": 10.0,
"step": 0.1,
"display": "slider" # or "number" for a numeric input field
})
For dropdown selectors:
"mode": (["option1", "option2", "option3"],)
Output Types
Common output types include:
IMAGE: Processed image dataMASK: Image mask dataLATENT: Latent space representationCONDITIONING: Conditioning data for samplersMODEL: Model data
Multi-Output Nodes
For nodes with multiple outputs:
RETURN_TYPES = ("IMAGE", "MASK")
RETURN_NAMES = ("output_image", "image_mask")
Advanced Node Development
Handling Batches of Images
To process batches efficiently:
def execute(self, image, intensity):
# image has shape [B, H, W, C]
batch_size = image.shape[0]
result = []
for i in range(batch_size):
# Process each image in the batch
img = image[i]
# Apply processing
processed = self.process_single_image(img, intensity)
result.append(processed)
# Stack results back into a batch
return (torch.stack(result),)
Integrating External Libraries
For nodes that use external libraries:
-
Add requirements to
requirements.txt:opencv-python>=4.5.0 scikit-image>=0.19.0 -
Import and use in your node:
import cv2 from skimage import filters class ImageProcessingNode: # ... def execute(self, image, params): # Convert to format for OpenCV img_np = (image.numpy() * 255).astype(np.uint8) # Process with CV2 processed = cv2.someFunction(img_np, params) # Convert back return (torch.from_numpy(processed / 255.0),)
Custom UI Components
For advanced UI elements, create a JavaScript file in web/js/:
// web/js/my_component.js
import { app } from "../../scripts/app.js";
app.registerExtension({
name: "MyCustomComponent",
async setup(app) {
// Register a custom widget
app.registerNodeDef("MyCustomNode", {
color: "#5588AA",
uiFields: {
"customParameter": (node, inputName) => {
// Create custom UI element
const widget = document.createElement("div");
widget.innerHTML = `<div class="custom-control">...</div>`;
return { element: widget };
}
}
});
}
});
Distributing Custom Nodes
Packaging
- Create a
README.mdwith installation and usage instructions - Include a
requirements.txtwith dependencies - Add example workflows in your documentation
- Include screenshots of the node in action
Installation Instructions
Provide clear installation instructions:
## Installation
1. Navigate to your ComfyUI custom_nodes directory
2. Clone this repository:
git clone https://github.com/username/my-custom-node.git
3. Install requirements:
cd my-custom-node pip install -r requirements.txt
4. Restart ComfyUI
Publishing
- Publish your code to GitHub
- Add your node to the ComfyUI Custom Nodes List
- Share in the ComfyUI Discord community
Best Practices
Performance
- Optimize tensor operations for speed
- Use batch processing where possible
- Consider adding a "preview" mode for complex operations
- Clean up resources in
__del__if needed
Compatibility
- Test with different ComfyUI versions
- Document minimum requirements
- Provide fallbacks for optional dependencies
- Handle different image formats and dimensions
User Experience
- Use clear, descriptive names for nodes and parameters
- Add tooltips with
DESCRIPTIONand input descriptions - Include examples in your documentation
- Add visual feedback for long-running operations
Error Handling
- Validate inputs before processing
- Provide clear error messages
- Handle edge cases gracefully
- Add debug logging for troubleshooting
Version Management
- Use semantic versioning
- Keep a changelog
- Test thoroughly before releasing updates
- Document breaking changes