# Extension points — Comfy-Org/ComfyUI

> Canonical page: https://codevetter.com/unpack/comfyui/extension-points

# Extension points — Comfy-Org/ComfyUI

Scanned commit b33e2b55cae074eca5aec96283cceac19aa249ba (2026-09-22). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

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. — [nodes.py#L2246-2304](https://github.com/Comfy-Org/ComfyUI/blob/b33e2b55cae074eca5aec96283cceac19aa249ba/nodes.py#L2246-L2304) [nodes.py#L56-77](https://github.com/Comfy-Org/ComfyUI/blob/b33e2b55cae074eca5aec96283cceac19aa249ba/nodes.py#L56-L77) [custom_nodes/example_node.py.example](https://github.com/Comfy-Org/ComfyUI/blob/b33e2b55cae074eca5aec96283cceac19aa249ba/custom_nodes/example_node.py.example)
- 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). — [nodes.py#L2305-2335](https://github.com/Comfy-Org/ComfyUI/blob/b33e2b55cae074eca5aec96283cceac19aa249ba/nodes.py#L2305-L2335) [comfy_api/latest/_io.py#L1704-1780](https://github.com/Comfy-Org/ComfyUI/blob/b33e2b55cae074eca5aec96283cceac19aa249ba/comfy_api/latest/_io.py#L1704-L1780) [comfy_api/latest/_io.py#L2296](https://github.com/Comfy-Org/ComfyUI/blob/b33e2b55cae074eca5aec96283cceac19aa249ba/comfy_api/latest/_io.py#L2296)
- 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. — [nodes.py#L2270-2292](https://github.com/Comfy-Org/ComfyUI/blob/b33e2b55cae074eca5aec96283cceac19aa249ba/nodes.py#L2270-L2292) [server.py#L356-368](https://github.com/Comfy-Org/ComfyUI/blob/b33e2b55cae074eca5aec96283cceac19aa249ba/server.py#L356-L368) [server.py#L1245-1247](https://github.com/Comfy-Org/ComfyUI/blob/b33e2b55cae074eca5aec96283cceac19aa249ba/server.py#L1245-L1247)
- 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). — [main.py#L183-237](https://github.com/Comfy-Org/ComfyUI/blob/b33e2b55cae074eca5aec96283cceac19aa249ba/main.py#L183-L237)
- 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). — [server.py#L1459-1470](https://github.com/Comfy-Org/ComfyUI/blob/b33e2b55cae074eca5aec96283cceac19aa249ba/server.py#L1459-L1470) [server.py#L1079](https://github.com/Comfy-Org/ComfyUI/blob/b33e2b55cae074eca5aec96283cceac19aa249ba/server.py#L1079)
- 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) — [server.py#L262-267](https://github.com/Comfy-Org/ComfyUI/blob/b33e2b55cae074eca5aec96283cceac19aa249ba/server.py#L262-L267) [server.py#L1236-1243](https://github.com/Comfy-Org/ComfyUI/blob/b33e2b55cae074eca5aec96283cceac19aa249ba/server.py#L1236-L1243)
- 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. — [main.py#L140-149](https://github.com/Comfy-Org/ComfyUI/blob/b33e2b55cae074eca5aec96283cceac19aa249ba/main.py#L140-L149) [utils/extra_config.py](https://github.com/Comfy-Org/ComfyUI/blob/b33e2b55cae074eca5aec96283cceac19aa249ba/utils/extra_config.py) [extra_model_paths.yaml.example](https://github.com/Comfy-Org/ComfyUI/blob/b33e2b55cae074eca5aec96283cceac19aa249ba/extra_model_paths.yaml.example) [folder_paths.py#L373-389](https://github.com/Comfy-Org/ComfyUI/blob/b33e2b55cae074eca5aec96283cceac19aa249ba/folder_paths.py#L373-L389)
- 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. — [execution.py#L64-105](https://github.com/Comfy-Org/ComfyUI/blob/b33e2b55cae074eca5aec96283cceac19aa249ba/execution.py#L64-L105) [execution.py#L503-522](https://github.com/Comfy-Org/ComfyUI/blob/b33e2b55cae074eca5aec96283cceac19aa249ba/execution.py#L503-L522) [execution.py#L884-893](https://github.com/Comfy-Org/ComfyUI/blob/b33e2b55cae074eca5aec96283cceac19aa249ba/execution.py#L884-L893) [comfy_execution/graph_utils.py](https://github.com/Comfy-Org/ComfyUI/blob/b33e2b55cae074eca5aec96283cceac19aa249ba/comfy_execution/graph_utils.py)
- 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. — [comfy_execution/cache_provider.py](https://github.com/Comfy-Org/ComfyUI/blob/b33e2b55cae074eca5aec96283cceac19aa249ba/comfy_execution/cache_provider.py) [execution.py#L714-725](https://github.com/Comfy-Org/ComfyUI/blob/b33e2b55cae074eca5aec96283cceac19aa249ba/execution.py#L714-L725)
- Progress reporting is extensible via add_progress_handler in comfy_execution/progress.py; WebUIProgressHandler is the built-in implementation forwarding to the websocket client. — [comfy_execution/progress.py](https://github.com/Comfy-Org/ComfyUI/blob/b33e2b55cae074eca5aec96283cceac19aa249ba/comfy_execution/progress.py) [execution.py#L753-754](https://github.com/Comfy-Org/ComfyUI/blob/b33e2b55cae074eca5aec96283cceac19aa249ba/execution.py#L753-L754)
- 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/feature_flags.py](https://github.com/Comfy-Org/ComfyUI/blob/b33e2b55cae074eca5aec96283cceac19aa249ba/comfy_api/feature_flags.py) [main.py#L7-11](https://github.com/Comfy-Org/ComfyUI/blob/b33e2b55cae074eca5aec96283cceac19aa249ba/main.py#L7-L11) [main.py#L436-447](https://github.com/Comfy-Org/ComfyUI/blob/b33e2b55cae074eca5aec96283cceac19aa249ba/main.py#L436-L447)
- 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). — [nodes.py#L2566-2575](https://github.com/Comfy-Org/ComfyUI/blob/b33e2b55cae074eca5aec96283cceac19aa249ba/nodes.py#L2566-L2575) [comfy_api/version_list.py](https://github.com/Comfy-Org/ComfyUI/blob/b33e2b55cae074eca5aec96283cceac19aa249ba/comfy_api/version_list.py) [comfy_api](https://github.com/Comfy-Org/ComfyUI/blob/b33e2b55cae074eca5aec96283cceac19aa249ba/comfy_api)
- NodeReplaceManager rewrites submitted prompt graphs (apply_replacements is invoked in post_prompt before validation) — a server-side node-substitution extension point. — [server.py#L1113](https://github.com/Comfy-Org/ComfyUI/blob/b33e2b55cae074eca5aec96283cceac19aa249ba/server.py#L1113) [app/node_replace_manager.py](https://github.com/Comfy-Org/ComfyUI/blob/b33e2b55cae074eca5aec96283cceac19aa249ba/app/node_replace_manager.py)
- 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). — [main.py#L117-137](https://github.com/Comfy-Org/ComfyUI/blob/b33e2b55cae074eca5aec96283cceac19aa249ba/main.py#L117-L137) [server.py#L245-246](https://github.com/Comfy-Org/ComfyUI/blob/b33e2b55cae074eca5aec96283cceac19aa249ba/server.py#L245-L246) [nodes.py#L2375-2378](https://github.com/Comfy-Org/ComfyUI/blob/b33e2b55cae074eca5aec96283cceac19aa249ba/nodes.py#L2375-L2378)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
