CodeVetter · Repo Unpack · Extension points
Comfy-Org/ComfyUI
ComfyUI's primary extension mechanism is the custom_nodes directory scanned at startup: V1 extensions export NODE_CLASS_MAPPINGS/NODE_DISPLAY_NAME_MAPPINGS dicts (and optional WEB_DIRECTORY for frontend JS), while V3 extensions expose a comfy_entrypoint() returning a ComfyExtension whose get_node_list() yields ComfyNode classes with declarative Schemas. Secondary hooks: prestartup_script.py per package, server.on_prompt_handlers for prompt mutation, custom aiohttp routes via PromptServer.instance.routes, extra model paths via yaml config, progress handlers, cache providers, and node replacement rules.
- V1 node contract: a module in custom_nodes/ exporting NODE_CLASS_MAPPINGS {name: class} where each class defines INPUT_TYPES (required/optional/hidden), RETURN_TYPES, FUNCTION (method name), CATEGORY; OUTPUT_NODE=True makes it an execution target; registered into the global registry by load_custom_node.
- V3 node contract: modules export comfy_entrypoint() (sync or async) returning a ComfyExtension; get_node_list() returns io.ComfyNode subclasses whose GET_SCHEMA() provides node_id, inputs/outputs as typed Input/Output objects, hidden flags, and behavior flags (is_output_node, not_idempotent, enable_expand, accept_all_inputs, loop_boundary).
- Frontend extension point: WEB_DIRECTORY module attr or pyproject.toml [tool.comfy] web dir registers a static JS dir served at /extensions/<name>; /extensions endpoint enumerates all JS for the frontend to import.
- Per-package prestartup hook: any custom_nodes/<pkg>/prestartup_script.py is exec'd before node loading, letting packages patch the environment early (used e.g. for dependency installs).
- Prompt mutation hook: PromptServer.add_on_prompt_handler registers callables run by trigger_on_prompt on every POST /prompt body before validation (exceptions are logged and skipped).
- HTTP route extension: custom nodes can append to PromptServer.instance.routes (the same RouteTableDef), and every added route is automatically mirrored under /api by add_routes. (inferred)
- Model path extension: extra_model_paths.yaml (example in repo root) and --extra-model-paths-config call utils.extra_config.load_extra_path_config which feeds folder_paths.add_model_folder_path to add search dirs per category.
- Execution hooks for nodes: IS_CHANGED/fingerprint_inputs controls cache reuse; check_lazy_status marks required inputs for lazy evaluation; VALIDATE_INPUTS/validate_inputs custom-validates; ExecutionBlocker short-circuits branches; GraphBuilder lets a node emit an 'expand' subgraph.
- Cache providers: comfy_execution/cache_provider.py exposes _get_cache_providers()/_has_cache_providers and PromptExecutor calls provider.on_prompt_start/on_prompt_end around each run — an external cache persistence seam.
- Progress reporting is extensible via add_progress_handler in comfy_execution/progress.py; WebUIProgressHandler is the built-in implementation forwarding to the websocket client.
- Feature flags: comfy_api/feature_flags.py maintains CLI_FEATURE_FLAG_REGISTRY (--list-feature-flag dumps it) and per-connection negotiation lets clients declare capabilities like supports_preview_metadata that change server behavior.
- Comfy API versioning seam: comfy_api/version_list.supported_versions are registered through register_versions(ComfyAPIWithVersion) in init_public_apis, letting custom nodes target a stable versioned API surface (v0_0_1, v0_0_2, latest).
- NodeReplaceManager rewrites submitted prompt graphs (apply_replacements is invoked in post_prompt before validation) — a server-side node-substitution extension point.
- comfyui_manager is an optional pip-installed extension enabled by --enable-manager that adds its own middleware, prestartup, and node-load policy hooks (should_be_disabled).