11 KiB
Custom Nodes
Custom Nodes can be added to ComfyUI by copying and pasting Python files into your ./custom_nodes directory.
Installing Custom Nodes
There are two kinds of custom nodes: vanilla custom nodes, which generally expect to be dropped into the custom_nodes directory and managed by a tool called the ComfyUI Extension manager ("vanilla" custom nodes) and this repository's opinionated, installable custom nodes ("installable").
Installing ComfyUI Manager
ComfyUI-Manager is a popular extension to help you install and manage other custom nodes. To install it, you will need git on your system.
Manual Install
The installation process for ComfyUI-Manager requires two steps: installing its Python dependencies, and then cloning its code into the custom_nodes directory.
-
Install dependencies. First, ensure you have installed
comfyuifrom this repository as described in the Installing section. Then, run the following command from your ComfyUI workspace directory (the one containing your.venvfolder) to install the extra dependencies for ComfyUI-Manager:uv pip install --torch-backend=auto --upgrade "comfyui[comfyui_manager]@git+https://github.com/hiddenswitch/ComfyUI.git" -
Clone the repository. Next, you need to clone the ComfyUI-Manager repository into the
custom_nodesdirectory within your ComfyUI workspace. Your workspace is the directory you created during the initial setup where you ranuv venv(e.g.,~/Documents/ComfyUI_Workspace).If the
custom_nodesdirectory does not exist in your workspace, create it first (e.g.,mkdir custom_nodes). Then, from your workspace directory, run the following command:git clone https://github.com/Comfy-Org/ComfyUI-Manager.git ./custom_nodes/ComfyUI-ManagerThis command will place the manager's code into
custom_nodes/ComfyUI-Manager/. -
Restart ComfyUI. After the cloning is complete, restart ComfyUI. You should now see a "Manager" button in the menu.
PyPi Install
ComfyUI-Manager is an extension that allows you to easily install, update, and manage custom nodes for ComfyUI.
Setup
-
Install the manager dependencies:
pip install -r manager_requirements.txt -
Enable the manager with the
--enable-managerflag when running ComfyUI:python main.py --enable-manager
Command Line Options
| Flag | Description |
|---|---|
--enable-manager |
Enable ComfyUI-Manager |
--enable-manager-legacy-ui |
Use the legacy manager UI instead of the new UI (requires --enable-manager) |
--disable-manager-ui |
Disable the manager UI and endpoints while keeping background features like security checks and scheduled installation completion (requires --enable-manager) |
Vanilla Custom Nodes
Clone the repository containing the custom nodes into custom_nodes/ in your working directory and install its requirements, or use the manager.
Custom Nodes Authored for this Fork
Run uv pip install "git+https://github.com/owner/repository", replacing the git repository with the installable custom nodes URL. This is just the GitHub URL.
Authoring Custom Nodes
These instructions will allow you to quickly author installable custom nodes.
Using pyproject.toml for projects with existing requirements.txt
Suppose your custom nodes called my_comfyui_nodes has a folder layout that looks like this:
__init__.py
some_python_file.py
requirements.txt
LICENSE.txt
some_directory/some_code.py
First, add an __init__.py to some_directory, so that it is a Python package:
__init__.py
some_python_file.py
requirements.txt
LICENSE.txt
some_directory/__init__.py
some_directory/some_code.py
Then, if your NODE_CLASS_MAPPINGS are declared in __init__.py, use the following as a pyproject.toml, substituting your actual project name:
pyproject.toml
[project]
name = "my_comfyui_nodes"
description = "My nodes description."
version = "1.0.0"
license = { file = "LICENSE.txt" }
dynamic = ["dependencies"]
[project.urls]
Repository = "https://github.com/your-github-username/my-comfyui-nodes"
# Used by Comfy Registry https://comfyregistry.org
[tool.comfy]
PublisherId = "your-github-username"
DisplayName = "my_comfyui_nodes"
Icon = ""
[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"
[tool.setuptools]
packages = ["my_comfyui_nodes", "my_comfyui_nodes.some_directory"]
package-dir = { "my_comfyui_nodes" = ".", "my_comfyui_nodes.some_directory" = "some_directory" }
[tool.setuptools.dynamic]
dependencies = { file = ["requirements.txt"] }
[project.entry-points."comfyui.custom_nodes"]
my_comfyui_nodes = "my_comfyui_nodes"
Observe that the directory should now be listed as a package in the packages and package-dir statement.
Using setup.py
Create a requirements.txt:
comfyui
Observe comfyui is now a requirement for using your custom nodes. This will ensure you will be able to access comfyui as a library. For example, your code will now be able to import the folder paths using from comfyui.cmd import folder_paths. Because you will be using my fork, use this:
comfyui @ git+https://github.com/hiddenswitch/ComfyUI.git
Additionally, create a pyproject.toml:
[build-system]
requires = ["setuptools", "wheel", "pip"]
build-backend = "setuptools.build_meta"
This ensures you will be compatible with later versions of Python.
Finally, move your nodes to a directory with an empty __init__.py, i.e., a package. You should have a file structure like this:
# the root of your git repository
/.git
/pyproject.toml
/requirements.txt
/mypackage_custom_nodes/__init__.py
/mypackage_custom_nodes/some_nodes.py
Finally, create a setup.py at the root of your custom nodes package / repository. Here is an example:
setup.py
from setuptools import setup, find_packages
import os.path
setup(
name="mypackage",
version="0.0.1",
packages=find_packages(),
install_requires=open(os.path.join(os.path.dirname(__file__), "requirements.txt")).readlines(),
author='',
author_email='',
description='',
entry_points={
'comfyui.custom_nodes': [
'mypackage = mypackage_custom_nodes',
],
},
)
All .py files located in the package specified by the entrypoint with your package's name will be scanned for node class mappings declared like this:
some_nodes.py:
from comfy.nodes.package_typing import CustomNode
class Binary_Preprocessor(CustomNode):
...
NODE_CLASS_MAPPINGS = {
"BinaryPreprocessor": Binary_Preprocessor
}
NODE_DISPLAY_NAME_MAPPINGS = {
"BinaryPreprocessor": "Binary Lines"
}
These packages will be scanned recursively.
Extending the comfy.nodes.package_typing.CustomNode provides type hints for authoring nodes.
Adding Custom Configuration
Declare an entry point for configuration hooks in your setup.py that defines a function that takes and returns an
configargparser.ArgParser object:
setup.py
setup(
name="mypackage",
...
entry_points = {
'comfyui.custom_nodes': [
'mypackage = mypackage_custom_nodes',
],
'comfyui.custom_config': [
'mypackage = mypackage_custom_config:add_configuration',
]
},
)
mypackage_custom_config.py:
import configargparse
def add_configuration(parser: configargparse.ArgParser) -> configargparse.ArgParser:
parser.add_argument("--openai-api-key",
required=False,
type=str,
help="Configures the OpenAI API Key for the OpenAI nodes", env_var="OPENAI_API_KEY")
return parser
You can now see your configuration option at the bottom of the --help command along with hints for how to use it:
$ comfyui --help
usage: comfyui.exe [-h] [-c CONFIG_FILE] [--write-out-config-file CONFIG_OUTPUT_PATH] [-w CWD] [-H [IP]] [--port PORT]
[--enable-cors-header [ORIGIN]] [--max-upload-size MAX_UPLOAD_SIZE] [--extra-model-paths-config PATH [PATH ...]]
...
[--openai-api-key OPENAI_API_KEY]
options:
-h, --help show this help message and exit
-c CONFIG_FILE, --config CONFIG_FILE
config file path
--write-out-config-file CONFIG_OUTPUT_PATH
takes the current command line args and writes them out to a config file at the given path, then exits
-w CWD, --cwd CWD Specify the working directory. If not set, this is the current working directory. models/, input/, output/ and other
directories will be located here by default. [env var: COMFYUI_CWD]
-H [IP], --listen [IP]
Specify the IP address to listen on (default: 127.0.0.1). If --listen is provided without an argument, it defaults to
0.0.0.0. (listens on all) [env var: COMFYUI_LISTEN]
--port PORT Set the listen port. [env var: COMFYUI_PORT]
...
--distributed-queue-name DISTRIBUTED_QUEUE_NAME
This name will be used by the frontends and workers to exchange prompt requests and replies. Progress updates will be
prefixed by the queue name, followed by a '.', then the user ID [env var: COMFYUI_DISTRIBUTED_QUEUE_NAME]
--external-address EXTERNAL_ADDRESS
Specifies a base URL for external addresses reported by the API, such as for image paths. [env var:
COMFYUI_EXTERNAL_ADDRESS]
--openai-api-key OPENAI_API_KEY
Configures the OpenAI API Key for the OpenAI nodes [env var: OPENAI_API_KEY]
You can now start comfyui with:
uv run comfyui --openai-api-key=abcdefg12345
or set the environment variable you specified:
export OPENAI_API_KEY=abcdefg12345
uv run comfyui
or add it to your config file:
config.yaml:
openapi-api-key: abcdefg12345
comfyui --config config.yaml
Since comfyui looks for a config.yaml in your current working directory by default, you can omit the argument if
config.yaml is located in your current working directory:
uv run comfyui
Your entry point for adding configuration options should not import your nodes. This gives you the opportunity to use the configuration you added in your nodes; otherwise, if you imported your nodes in your configuration entry point, the nodes will potentially be initialized without any configuration.
Access your configuration from cli_args:
from comfy.cli_args import args
from comfy.cli_args_types import Configuration
from typing import Optional
# Add type hints when accessing args
class CustomConfiguration(Configuration):
def __init__(self):
super().__init__()
self.openai_api_key: Optional[str] = None
args: CustomConfiguration
class OpenAINode(CustomNode):
...
def execute(self):
openai_api_key = args.open_api_key