Open-Source Wikis

/

ComfyUI

/

Packages

/

comfy_api/

comfyanonymous/ComfyUI

comfy_api/

The versioned public API for custom-node authors. Anything a custom node imports from comfy_api.* is meant to stay stable across releases (modulo experimental surfaces in latest).

Layout

comfy_api/
├── feature_flags.py        # Frontend/backend feature flag negotiation
├── generate_api_stubs.py   # Pydantic stub generator for comfy_api_nodes/apis/
├── version_list.py         # supported_versions list
├── util.py
├── util/                   # Helpers
├── torch_helpers/          # Tensor helpers usable from custom nodes
├── input/, input_impl/     # (deprecated, kept for compat)
├── internal/               # Private types — do not import from custom nodes
│   ├── async_to_sync.py    # create_sync_class wrapper
│   ├── api_registry.py     # Version registry
│   └── singleton.py        # ProxiedSingleton
├── latest/                 # The current (unstable) public surface
│   ├── _io.py, _io_public.py    # IO types and Schema for V3 nodes
│   ├── _ui.py, _ui_public.py    # UI helpers
│   ├── _caching.py              # CacheProvider, CacheContext, CacheValue
│   ├── _input/, _input_impl/    # Image/Audio/Video/Mask/Latent input wrappers
│   ├── _util/                   # Misc helpers (VideoCodec, VideoContainer, …)
│   └── generated/               # Generated sync stubs
├── v0_0_1/                 # Frozen v0.0.1 surface
└── v0_0_2/                 # Frozen v0.0.2 surface

What's in latest

The most-used names a custom node imports:

Name What it is
io.Schema The V3 node schema constructor
io.ComfyNode Base class for V3 nodes
io.NodeOutput Wrapper around node outputs
io.Image / Audio / Video / Mask / Latent / Float / Int / String / Boolean IO type declarations for Schema inputs and outputs
io.Hidden Hidden inputs (prompt, dynprompt, extra_pnginfo, unique_id, …)
ui (alias UI) UI-side helpers (e.g. node display options)
ComfyExtension Abstract base for an extension; implements get_node_list()
Input namespace Image, Audio, Mask, Latent, Video input wrappers (typed)
InputImpl Concrete impls: VideoFromFile, VideoFromComponents
Types VideoCodec, VideoContainer, VideoComponents, MESH, VOXEL, File3D
Caching External cache provider API (register_provider, unregister_provider, CacheProvider, …)
Execution.set_progress Report progress from inside a node
NodeReplacement.register Register a runtime node replacement

The full surface is in comfy_api/latest/__init__.py.

V3 schema example

The smallest possible V3 node, from comfy_extras/nodes_canny.py:

from comfy_api.latest import ComfyExtension, io
from typing_extensions import override

class Canny(io.ComfyNode):
    @classmethod
    def define_schema(cls):
        return io.Schema(
            node_id="Canny",
            display_name="Canny",
            category="image/preprocessors",
            inputs=[
                io.Image.Input("image"),
                io.Float.Input("low_threshold", default=0.4, min=0.01, max=0.99, step=0.01),
                io.Float.Input("high_threshold", default=0.8, min=0.01, max=0.99, step=0.01),
            ],
            outputs=[io.Image.Output()],
        )

    @classmethod
    def execute(cls, image, low_threshold, high_threshold) -> io.NodeOutput:
        ...
        return io.NodeOutput(img_out)

class CannyExtension(ComfyExtension):
    @override
    async def get_node_list(self) -> list[type[io.ComfyNode]]:
        return [Canny]

async def comfy_entrypoint() -> CannyExtension:
    return CannyExtension()

Compare with the V1 style in comfy/comfy_types/node_typing.py's ComfyNodeABC: V3 collapses INPUT_TYPES, RETURN_TYPES, FUNCTION, CATEGORY, and friends into a single declarative Schema and uses an execute classmethod.

Versioning

comfy_api/version_list.py lists the supported versions. The version registry under comfy_api/internal/api_registry.py tracks them. Custom nodes pin via from comfy_api.latest import ..., from comfy_api.v0_0_2 import ..., etc.

The repo guarantees:

  • latest may break between releases.
  • v0_0_1, v0_0_2 (and future stable tags) are frozen — once shipped, the surface doesn't change.

comfy_api/internal/ is private and may change at any time, even though it's importable.

Feature flags

comfy_api/feature_flags.py negotiates frontend/backend capability flags so the server knows whether the connected client supports new features (e.g., supports_preview_metadata, used in hijack_progress in main.py).

Async-to-sync

comfy_api/internal/async_to_sync.py defines create_sync_class — a wrapper that turns the async ComfyAPI_latest into a synchronous ComfyAPISync mirror. This is generated at runtime so custom nodes can call API methods from sync code without spawning event loops.

Stub generation

comfy_api/generate_api_stubs.py regenerates the Pydantic schemas in comfy_api_nodes/apis/. Run it after editing schemas under comfy_api_nodes/apis/schemas/. CI runs it via update-api-stubs.yml.

Integration points

  • Imported by nodes.py, every comfy_extras/*.py written in V3, and most comfy_api_nodes/*.py.
  • Wraps the executor's progress and caching subsystems so custom nodes don't have to reach into comfy_execution/ directly.
  • Exposes IO types tied to comfy/comfy_types/node_typing.py (IO.IMAGE, IO.LATENT, etc.).

Where to start a change

  • Adding a new IO type: extend comfy/comfy_types/node_typing.py:IO and the V3 schema helpers in comfy_api/latest/_io.py. Don't forget the public re-export in comfy_api/latest/_io_public.py.
  • New API method visible to custom nodes: add an async def on a ProxiedSingleton subclass in comfy_api/latest/__init__.py. The sync wrapper is generated automatically.
  • Bumping the version surface: add a new comfy_api/v0_0_3/ snapshot and add it to version_list.supported_versions.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

comfy_api/ – ComfyUI wiki | Factory