Skip to content

Your First ComfyUI Custom Node: A Step-by-Step Guide

ComfyUI’s power lies in its node-based workflow, which allows users to create complex image generation pipelines. Custom nodes extend this functionality, allowing you to add unique image processing, data manipulation, or even connect to external APIs. This guide will walk you through creating a simple custom node to get you started.

This node will delay the execution of the nodes following it by x seconds.

Note: I have used the code from a node I made for the creepy_nodes pack, available on Github.

Prerequisites

Before you begin, ensure you have the following:

ComfyUI Installed: You need a working ComfyUI installation. If you haven’t already, follow the installation instructions on the official ComfyUI GitHub repository.

Python Environment: ComfyUI uses Python. Ensure you have Python 3.8 or higher installed. It’s highly recommended to use a virtual environment to manage dependencies.

Basic Python Knowledge: A basic understanding of Python syntax, functions, and classes is necessary.

A text editor: A text editor to write your code in, I personally use Atom, but you can use whichever you prefer.

Step 1: Setting up the your Custom Nodes Directory

First, you’ll need to create a directory where ComfyUI will look for your custom nodes. This directory should be located in the custom_nodes directory and named something simple and original.

Navigate to custom_nodes directory in your ComfyUI installation directory.

Create a folder named test_node.

Step 2: Creating the Node’s Python File

Now, let’s create the Python file that will define your custom node. We’ll create a simple node that delays the execution of the nodes following it.

Inside the custom_nodes directory, navigate to the folder you created and named test_node. This helps organize your custom nodes, especially as you create more.

Inside the test_nodes directory, create a new Python file. Name it nodes.py (it says wrong in the image). This file will contain the code for your node.

Step 3: Writing the Node’s Code

Open nodes.py in your text editor or IDE and add the following code:

import time

class TestNode:
    def __init__(self):
        pass

    @classmethod
    def INPUT_TYPES(cls):
        return {
            "required": {
                "seconds": ("FLOAT", {"default": 1.0, "min": 0.1, "step": 0.1}),
                "image": ("IMAGE",),  # Specific input type for images
            },
        }

    RETURN_TYPES = ("IMAGE",)  # Specific return type for images
    RETURN_NAMES = ("image",)
    FUNCTION = "delay"
    CATEGORY = "Test Node/Delay Node"

    def delay(self, seconds, image):
        """
        Delays execution for the specified number of seconds.

        Args:
            seconds (float): The number of seconds to delay (minimum 0.1, step 0.1).
            image (torch.Tensor): The input image.

        Returns:
            torch.Tensor: The input image after the delay.
        """
        if seconds < 0.1:
            seconds = 0.1 #Enforce minimum value.

        time.sleep(seconds)
        return (image,)


NODE_CLASS_MAPPINGS = {
      "TestNode": TestNode,
}

NODE_DISPLAY_NAME_MAPPINGS = {
      "TestNode": "Test Node (My Test Node)",
}

Let’s break down the code and go through what the different part is really doing.

This line imports the time module, which provides the sleep function used to pausing the execution.

This defines the class for your custom node. The name of the class will be used internally by ComfyUI.

def INPUT_TYPES(cls) will define what types of input that your node will accept. “Required” indicates that the input is mandatory. “Seconds” is the display name of the value you can input and (“FLOAT”, {“default”: 1.0, “min”: 0.1, “step”: 0.1}) defines the datat type of the input, in this case a default value of 1 second and a minimum value of 0.1 seconds and the ability to change the value in 0.1 second steps.

“image” is the display name of your next input and (“IMAGE”,) specifies that your node require this input to be an image.

The RETURN_TYPES = (“IMAGE”,) specifies the data output of your node, in this case an image, and the RETURN_NAMES = (“image”,) specifies the display name of the output. The FUNCTION = “delay” tells ComfyUI which method in the class to call when the node is executed. The CATEGORY = “Test Node/Utilities” determines how your node will be listed in ComfyUI, for example will this node be listed under “Test Node” and “Utilities”.

The delay(self, seconds, image) tells the node the execute the delay of the input number in seconds. It takes the seconds and image as input and uses time.sleep(seconds) to pause the execution.

The NODE_CLASS_MAPPINGS is a dictionary that maps the class name (“TestNode”) to the actual class (TestNode) and is how ComfyUI finds your node. The NODE_DISPLAY_NAME_MAPPINGS is a dictionary that maps the class name (“TestNode”) to a more userfriendly name (“Test Node (My Test Node)”) and is how your node will be displayed in ComfyUI.

Your custom node is now complete but in order for ComfyUI to be able to load it, you will also have to create an __init__.py file.

Step 4: Creating the __init__.py File

To tell Python that your ComfyUI_MyTestNodes directory is a Python package (a collection of modules), you need to create an __init__.py file inside it. This file can be empty, but it must exist.

In your test_node folder, create a file and name it __init__.py and open it in your text editor. Add the following code and save the file.

from .nodes import NODE_CLASS_MAPPINGS as nodes_NODE_CLASS_MAPPINGS, NODE_DISPLAY_NAME_MAPPINGS as nodes_NODE_DISPLAY_NAME_MAPPINGS

__version__ = "1.1.1"

# Define the web directory for ComfyUI to find our JavaScript files
WEB_DIRECTORY = "./web"

NODE_CLASS_MAPPINGS = {
    **nodes_NODE_CLASS_MAPPINGS,
}

NODE_DISPLAY_NAME_MAPPINGS = {
    **nodes_NODE_DISPLAY_NAME_MAPPINGS,
}

__all__ = ['NODE_CLASS_MAPPINGS', 'NODE_DISPLAY_NAME_MAPPINGS', 'WEB_DIRECTORY']

This will tell ComfyUI where your node is and where to find the class and name mappings. If you are only making one or a few nodes, you can just write your next node after your first one in nodes.py. If you plan to create more nodes, it would be better to create a separate python file for each node, and import them all in this __init__.py file.

Now you can restart (or start) ComfyUI, open an empty workflow and double-click somewhere on it to open up the search menu. Type “test node” in the search bar, and your node should show up in the list.

test node

You can also find your node in the nodes library, according to the category we previsously set in the nodes.py code.

And you can use the node in any workflow you build. Note that for now you are only able to use the node locally in your own workflows, and if you share the workflow with your node to someone else they wont be able to find or use your node.

If there’s enough interest in this post and people wish me to, I’ll explain in another post how to make your node public and publish it to the ComfyUI manager.

For inspiration on new nodes to create, I suggest you visit the github of any node creator and check out what they have made and how they write their code.

Please share this post with friends that are interested in AI and developing custom nodes and workflows for ComfyUI. Follow me at

Instagram
TikTok
Facebook
YouTube
CivitAI

Published inAIComfyUITech