Agent skill

ComfyUI Frontend Extensions

by jtydhr88 in jtydhr88/comfyui-custom-node-skills

Guide to writing JavaScript extensions for the ComfyUI frontend from custom nodes, covering lifecycle hooks, widgets, sidebar tabs, commands, settings, toasts and dialogs.

MITAuto-check passedFrontend & Design

Install ComfyUI Frontend Extensions

skills CLI
$ npx skills add jtydhr88/comfyui-custom-node-skills --skill comfyui-node-frontend -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install jtydhr88/comfyui-custom-node-skills comfyui-node-frontend --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/jtydhr88/comfyui-custom-node-skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/plugins/comfyui-custom-nodes/skills/comfyui-node-frontend .claude/skills/comfyui-node-frontend && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
comfyui-node-frontend
GitHub stars
294
Token cost
~3.7k tokens
SKILL.md length
435 words
Files
2
Skills in repo
9
Repo updated
First seen
Licence
MIT

At a glance

Guide to writing JavaScript extensions for the ComfyUI frontend from custom nodes, covering lifecycle hooks, widgets, sidebar tabs, commands, settings, toasts and dialogs.

  • Works in 2 steps: Export WEB_DIRECTORY in Python → Create JavaScript Extension
  • Adding UI features to a ComfyUI custom node
  • SKILL.md covers Quick Start, Extension Hooks (Lifecycle…, Custom Widgets and Declarative Extension Properties
  • Reaches github.com

What it does

This skill shows how a custom node can extend the ComfyUI frontend with JavaScript. The quick start exports WEB_DIRECTORY from the node's Python package, pointing at a js folder, then adds a JavaScript file that imports app and calls registerExtension. Every .js file in that directory loads when ComfyUI starts.

Hooks are documented in lifecycle order with examples: init, addCustomNodeDefs, getCustomWidgets, beforeRegisterNodeDef, nodeCreated, setup, loadedGraphNode, registerCustomNodes, beforeRegisterVueAppNodeDefs, and beforeConfigureGraph with afterConfigureGraph. The description also covers sidebar tabs, commands, settings, toasts and dialogs, and a separate api-reference.md file backs it up. It belongs to a collection of ComfyUI custom node skills that targets both the V3 and legacy V1 node APIs.

When your agent uses it

  • Adding UI features to a ComfyUI custom node
  • Creating a custom widget type for node inputs
  • Registering a sidebar tab, command or setting from an extension
  • Restoring node state when a saved graph loads

Example prompts

  • “Add a custom color-picker widget to my ComfyUI node using getCustomWidgets.”
  • “Set up WEB_DIRECTORY and a JS extension that shows a toast when a node finishes executing.”
  • “Hook loadedGraphNode so my node restores its saved state.”

Requirements

  • A ComfyUI custom node package with a Python __init__.py
  • A running ComfyUI installation to load the extension

Workflow steps

2 steps, taken from the step headings in SKILL.md.

  1. Export WEB_DIRECTORY in Python
  2. Create JavaScript Extension

What it can do on your machine

Read from SKILL.md and the folder at commit 63a78dc. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are javascript and python).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Hosts in commands or code, which the agent is likely to contact:

    • github.com

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

ComfyUI Frontend Extensions loads about 3.7k tokens when it runs. Until then it costs about 59 tokens; SKILL.md has 435 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~59
When it runs · the whole SKILL.md, loaded when a task matches
~3.7k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from jtydhr88/comfyui-custom-node-skills at commit 63a78dc, republished under its MIT licence (© jtydhr88). 435 words, ~3,704 tokens.

Download SKILL.mdSave it as .claude/skills/comfyui-node-frontend/SKILL.md (or your agent's skills folder). This skill also uses 1 other file; get the full folder from GitHub.
name
comfyui-node-frontend
description
ComfyUI frontend JavaScript extensions - hooks, widgets, sidebar tabs, commands, settings, toasts, dialogs. Use when adding UI features to custom nodes, creating custom widgets, or extending the ComfyUI frontend.

ComfyUI Frontend Extensions

Custom nodes can extend the ComfyUI frontend with JavaScript. Extensions register hooks, widgets, commands, settings, and UI components.

Quick Start

1. Export WEB_DIRECTORY in Python
python
# __init__.py
WEB_DIRECTORY = "./js"
__all__ = ["WEB_DIRECTORY"]
2. Create JavaScript Extension
javascript
// js/my_extension.js
import { app } from "../../scripts/app.js";

app.registerExtension({
    name: "my_nodes.my_extension",

    async setup() {
        console.log("Extension loaded!");
    },
});

All .js files in WEB_DIRECTORY are loaded automatically when ComfyUI starts.

Extension Hooks (Lifecycle Order)

init — After canvas created, before nodes
javascript
app.registerExtension({
    name: "my.ext",
    async init(app) {
        // Modify core behavior, add global listeners
    },
});
addCustomNodeDefs — Modify node definitions
javascript
async addCustomNodeDefs(defs, app) {
    // defs is a dict of all node definitions
    // Can add or modify definitions before registration
    defs["MyFrontendNode"] = {
        input: { required: { text: ["STRING", {}] } },
        output: ["STRING"],
        output_name: ["text"],
        name: "MyFrontendNode",
        display_name: "My Frontend Node",
        category: "custom",
    };
},
getCustomWidgets — Register custom widget types
javascript
getCustomWidgets(app) {
    return {
        MY_WIDGET(node, inputName, inputData, app) {
            const widget = node.addWidget("text", inputName, "", () => {});
            widget.serializeValue = () => widget.value;
            return { widget };
        },
    };
},
beforeRegisterNodeDef — Modify node prototype
javascript
async beforeRegisterNodeDef(nodeType, nodeData, app) {
    if (nodeData.name === "MyNode") {
        // Chain onto prototype methods
        const origOnCreated = nodeType.prototype.onNodeCreated;
        nodeType.prototype.onNodeCreated = function () {
            origOnCreated?.apply(this, arguments);
            // Add custom widget, modify behavior, etc.
            this.addWidget("button", "Run", null, () => {
                console.log("Button clicked!");
            });
        };
    }
},
nodeCreated — After node instance created
javascript
nodeCreated(node, app) {
    if (node.comfyClass === "MyNode") {
        // Modify this specific node instance
        node.color = "#335";
    }
},
setup — After app fully loaded
javascript
async setup(app) {
    // Add event listeners, register UI components
    app.api.addEventListener("executed", (event) => {
        console.log("Node executed:", event.detail);
    });
},
loadedGraphNode — When loading saved graph
javascript
loadedGraphNode(node, app) {
    if (node.comfyClass === "MyNode") {
        // Restore state from saved graph
    }
},
registerCustomNodes — Register additional node types
javascript
registerCustomNodes(app) {
    // Register custom LiteGraph node types
},
beforeRegisterVueAppNodeDefs — Modify node defs before Vue registration
javascript
beforeRegisterVueAppNodeDefs(defs, app) {
    // Modify definitions before they reach the Vue app
},
beforeConfigureGraph / afterConfigureGraph
javascript
async beforeConfigureGraph(graphData, missingNodeTypes, app) {
    // Before graph data is applied
},
async afterConfigureGraph(missingNodeTypes, app) {
    // After graph is fully configured
},
getSelectionToolboxCommands — Add commands to selection toolbox
javascript
getSelectionToolboxCommands(selectedItem) {
    // Return array of command IDs to show when item is selected
    return ["my.ext.doSomething"];
},
onNodeOutputsUpdated — Execution outputs changed
javascript
onNodeOutputsUpdated(nodeOutputs) {
    // nodeOutputs: Record<NodeLocatorId, output data>, fired when node outputs update
},
Authentication Hooks
javascript
onAuthUserResolved(user, app) {
    // Fires when user authentication resolves
},
onAuthTokenRefreshed() {
    // Fires when auth token is refreshed
},
onAuthUserLogout() {
    // Fires when user logs out
},

Custom Widgets

Adding DOM Widgets
javascript
beforeRegisterNodeDef(nodeType, nodeData, app) {
    if (nodeData.name === "MyNode") {
        const origOnCreated = nodeType.prototype.onNodeCreated;
        nodeType.prototype.onNodeCreated = function () {
            origOnCreated?.apply(this, arguments);

            const container = document.createElement("div");
            container.innerHTML = `<input type="color" value="#ff0000">`;
            container.querySelector("input").addEventListener("change", (e) => {
                this.widgets.find(w => w.name === "color").value = e.target.value;
            });

            this.addDOMWidget("colorPicker", "custom", container, {
                serialize: true,
                getValue() { return container.querySelector("input").value; },
                setValue(v) { container.querySelector("input").value = v; },
            });
        };
    }
},
Widget Hooks
javascript
// Called before prompt is queued
// isPartialExecution is true when only selected nodes are queued
widget.beforeQueued = function ({ isPartialExecution } = {}) {
    // Prepare widget value
};

// Called after prompt is queued
widget.afterQueued = function ({ isPartialExecution } = {}) {
    // Reset or update widget (e.g. control_after_generate)
};

// Custom serialization
widget.serializeValue = function (node, index) {
    return JSON.stringify(this.value);
};

Declarative Extension Properties

Commands
javascript
app.registerExtension({
    name: "my.ext",
    commands: [
        {
            id: "my.ext.doSomething",
            label: "Do Something",
            icon: "pi pi-bolt",
            function: () => { console.log("Executed!"); },
        },
    ],
});
Keybindings
javascript
keybindings: [
    {
        commandId: "my.ext.doSomething",
        combo: { key: "d", ctrl: true, shift: true },
    },
],
Settings
javascript
settings: [
    {
        id: "my.ext.mySetting",
        name: "My Setting",
        type: "boolean",
        defaultValue: true,
        onChange: (value) => { console.log("Setting changed:", value); },
    },
    {
        id: "my.ext.mode",
        name: "Processing Mode",
        type: "combo",
        options: ["fast", "quality", "balanced"],
        defaultValue: "balanced",
    },
],

Setting types: boolean, number, slider, knob, combo, radio, text, image, color, url, hidden, backgroundImage

Sidebar Tabs
javascript
async setup(app) {
    app.extensionManager.registerSidebarTab({
        id: "my-sidebar",
        title: "My Panel",
        icon: "pi pi-cog",
        type: "custom",
        render: (container) => {
            container.innerHTML = "<h3>My Custom Panel</h3>";
        },
        destroy: () => {
            // Cleanup
        },
    });
},
Bottom Panel Tabs
javascript
bottomPanelTabs: [
    {
        id: "my-panel",
        title: "My Panel",
        type: "custom",
        render: (container) => {
            container.innerHTML = "<div>Panel content</div>";
        },
    },
],
Menu Commands
javascript
menuCommands: [
    {
        path: ["My Extension"],
        commands: ["my.ext.doSomething"],
    },
],
About Page Badges
javascript
aboutPageBadges: [
    { label: "v1.0.0", url: "https://github.com/...", icon: "pi pi-github", severity: "warn" },
    // severity is optional: "danger" | "warn"
],
Top Bar Badges
javascript
topbarBadges: [
    {
        text: "My Extension",        // required
        label: "BETA",               // optional badge label
        variant: "info",             // "info" | "warning" | "error"
        icon: "pi pi-star",          // optional icon
        tooltip: "Extension info",   // optional tooltip
    },
],
Action Bar Buttons
javascript
actionBarButtons: [
    {
        icon: "pi pi-bolt",           // required
        label: "My Action",           // optional label
        tooltip: "Run my action",     // optional tooltip
        onClick: () => { /* ... */ },  // required click handler
    },
],

API Events

Listen to execution events:

javascript
// Node execution completed
app.api.addEventListener("executed", ({ detail }) => {
    const { node, output } = detail;
    // output contains images, text, etc.
});

// Execution progress
app.api.addEventListener("progress", ({ detail }) => {
    const { value, max, node } = detail;
});

// Execution started/completed
app.api.addEventListener("execution_start", ({ detail }) => {});
app.api.addEventListener("execution_success", ({ detail }) => {});
app.api.addEventListener("execution_error", ({ detail }) => {});

// Status updates
app.api.addEventListener("status", ({ detail }) => {
    const { exec_info } = detail;
});

Server-to-Client Communication

Python (server side):
python
from server import PromptServer

PromptServer.instance.send_sync(
    "my_extension.update",
    {"status": "complete", "data": result}
)
JavaScript (client side):
javascript
app.api.addEventListener("my_extension.update", ({ detail }) => {
    console.log("Received:", detail);
});

Toast Notifications

javascript
app.extensionManager.toast.add({
    severity: "info",  // "success", "info", "warn", "error"
    summary: "Title",
    detail: "Message content",
    life: 3000,  // auto-dismiss after ms
});

Dialogs

javascript
// Confirmation dialog
const result = await app.extensionManager.dialog.confirm({
    title: "Confirm Action",
    message: "Are you sure?",
});

// Prompt dialog
const value = await app.extensionManager.dialog.prompt({
    title: "Enter Value",
    message: "Provide a name:",
    defaultValue: "default",
});

ExtensionManager Utilities

Setting Access
javascript
// Read a setting value
const val = app.extensionManager.setting.get("my.ext.mySetting");

// Write a setting value
app.extensionManager.setting.set("my.ext.mySetting", newValue);
Execution Errors (read-only)
javascript
// Last node-level errors (keyed by node ID)
const nodeErrors = app.extensionManager.lastNodeErrors;

// Last execution-level error
const execError = app.extensionManager.lastExecutionError;
Markdown Rendering
javascript
// Render markdown to sanitized HTML (marked + DOMPurify, safe for innerHTML)
const html = app.extensionManager.renderMarkdownToHtml(markdownStr, baseUrl);

Context Menu Items

javascript
app.registerExtension({
    name: "my.ext",

    // Canvas right-click menu
    getCanvasMenuItems(canvas) {
        return [{
            content: "My Action",
            callback: () => { console.log("Canvas menu clicked"); },
        }];
    },

    // Node right-click menu
    getNodeMenuItems(node) {
        if (node.comfyClass === "MyNode") {
            return [{
                content: "Custom Action",
                callback: () => { console.log("Node:", node.id); },
            }];
        }
        return [];
    },
});

Node Instance Properties (LGraphNode Augmentations)

javascript
// Available on node instances:
node.comfyClass       // ComfyUI node type name
node.isVirtualNode    // true for frontend-only nodes
node.imgs             // preview images array
node.imageIndex       // current preview image index

// Callbacks:
node.onExecuted = function(output) { /* execution result */ };
node.onExecutionStart = function() { /* about to execute */ };
node.onDragOver = function(event) { /* file drag over */ };
node.onDragDrop = function(event) { /* file dropped */ };

Recent Breaking Changes (frontend ≥ 1.4x, mid-2026)

Changes extension authors should be aware of:

  • Group nodes removed — group nodes can no longer be created; workflows containing them auto-convert to subgraphs on load. GroupNodeHandler / GroupNodeConfig remain re-exported for backward compatibility only. Use subgraphs for new work.
  • LiteGraph.use_uuids removed — node IDs are always numeric. Don't read or set this flag (UUIDs are still used internally for subgraph/slot IDs).
  • LGraph.onGetNodeMenuOptions removed; LGraph.onBeforeChange deprecated — assigning it still works but warns; use LGraphCanvas.onBeforeChange instead.
  • IBaseWidget.entityId removed — widget identity is the widgetId branded key (graphId:nodeId:name); promoted subgraph widgets are store-backed.
  • node.size is Proxy-backed — both node.size[1] = h and node.size = [w, h] now correctly reflow Vue-rendered nodes; no polling workarounds needed.
Show full SKILL.md (139 more words)Show less

Frontend Scripts API

Custom node JavaScript can import from the frontend's src/scripts/ modules. Imports use the Vite shim pattern:

javascript
import { app } from "../../scripts/app.js";
import { api } from "../../scripts/api.js";

Symbols are also accessible via window.comfyAPI.<module>.<export>.

Stability Levels
LevelModulesNotes
Stablescripts/app, scripts/apiGuaranteed public API
Internal (console warning)scripts/widgets, scripts/domWidget, scripts/utils, scripts/pnginfo, scripts/changeTracker, scripts/defaultGraph, scripts/metadata/*Usable but may change
Deprecatedscripts/uiWill be removed; use Vue alternatives
Key Modules
  • scripts/api — ComfyApi class: fetchApi(), queuePrompt(), getNodeDefs(), WebSocket events, settings, user data, system stats
  • scripts/app — ComfyApp singleton (app): graph operations, registerExtension(), extensionManager, clipboard, coordinate conversion
  • scripts/widgets — ComfyWidgets registry (INT, FLOAT, STRING, BOOLEAN, COMBO, IMAGEUPLOAD, etc.), addValueControlWidgets()
  • scripts/domWidget — addDOMWidget(), DOMWidgetImpl, ComponentWidgetImpl (Vue component wrapper)
  • scripts/utils — clone(), addStylesheet(), uploadFile(), downloadBlob(), storage helpers
  • scripts/pnginfo — getPngMetadata(), getWebpMetadata(), importA1111(), format-specific extractors

For full API details, see the API Reference.

See Also

  • comfyui-node-basics - Backend node structure
  • comfyui-node-packaging - Project structure with JS extensions
  • comfyui-node-inputs - Backend input types

© jtydhr88, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 1 other file in plugins/comfyui-custom-nodes/skills/comfyui-node-frontend of jtydhr88/comfyui-custom-node-skills.

  • SKILL.md
  • api-reference.md

Open the folder on GitHubat commit 63a78dc

Compare with similar skills

ComfyUI Frontend Extensions next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

ComfyUI Frontend Extensions compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
ComfyUI Frontend Extensions this skilljtydhr88/comfyui-custom-node-skills294—~3.7kAutomated safety check: PassMIT
ComfyUI Custom Node BuilderConstantineB6/comfy-pilot230—~897Automated safety check: PassMIT
Setupguaardvark/guaardvark2551 repos~1.2kAutomated safety check: PassMIT
AI Toolkit Trainerartokun/comfyui-mcp795—~2.7kAutomated safety check: PassMIT
Add Comfyui NodeMooshieblob1/MooshieUI207—~936Automated safety check: PassAGPL-3.0
Edit Comfy Workflowpeteromallet/VibeComfy150—~2.2kAutomated safety check: PassMIT

Similar skills

  • ComfyUI Custom Node Builder

    ConstantineB6/comfy-pilot

    Helps an agent write ComfyUI custom nodes in Python, including wrapping an existing script, mapping data types and handling image batches.

    230 GitHub stars~897 tokensUpdated 7 mo ago
    AI & LLM EngineeringAuto-check passed
  • Setup

    guaardvark/guaardvark

    Connect this agent to a running Guaardvark (self-hosted AI studio) and check what it can do right now.

    255 GitHub starsUsed in 1 repo~1.2k tokens
    AI & LLM EngineeringAuto-check passed
  • AI Toolkit Trainer

    artokun/comfyui-mcp

    Train custom LoRAs with ostris AI-Toolkit. An agent skill from artokun/comfyui-mcp.

    795 GitHub stars~2.7k tokensUpdated 3 days ago
    AI & LLM EngineeringAuto-check passed
  • Add Comfyui Node

    Mooshieblob1/MooshieUI

    Adds a custom ComfyUI Python node to MooshieUI — Python class in mooshienodes.py, Rust required-class registration, and optional workflow template chain hookup.

    207 GitHub stars~936 tokensUpdated today
    AI & LLM EngineeringAuto-check passed
  • Edit Comfy Workflow

    peteromallet/VibeComfy

    Edit an existing VibeComfy or ComfyUI workflow, ready template, recipe, scratchpad, or target graph.

    150 GitHub stars~2.2k tokensUpdated 6 days ago
    AI & LLM EngineeringAuto-check passed
  • Comfyui Launch Flags

    artokun/comfyui-mcp

    Pick the right ComfyUI startup flags for VRAM, attention, caching, and speed.

    795 GitHub stars~3.1k tokensUpdated 3 days ago
    AI & LLM EngineeringAuto-check passed

More from jtydhr88/comfyui-custom-node-skills

All 9 skills in this repo
  • ComfyUI Advanced Node Patterns

    jtydhr88/comfyui-custom-node-skills

    Reference for ComfyUI V3 node patterns such as MatchType, MultiType, Autogrow and DynamicCombo, used to build nodes with dynamic inputs and type matching.

    294 GitHub stars~3.3k tokensUpdated 2 mo ago
    Auto-check passed
  • ComfyUI Custom Node Basics

    jtydhr88/comfyui-custom-node-skills

    Explains the V3 API for ComfyUI custom nodes: node classes, schema, inputs and outputs, registration and how it differs from the legacy V1 style.

    294 GitHub stars~1.6k tokensUpdated 2 mo ago
    Auto-check passed
  • ComfyUI Node Datatypes

    jtydhr88/comfyui-custom-node-skills

    Lists ComfyUI node data types, from IMAGE, MASK and LATENT tensors to model types, with their V3 classes and formats.

    294 GitHub stars~4.3k tokensUpdated 2 mo ago
    Auto-check passed
  • Comfyui Node Inputs

    jtydhr88/comfyui-custom-node-skills

    ComfyUI node input types - INT, FLOAT, STRING, BOOLEAN, COMBO widgets, hidden inputs, optional inputs, lazy inputs, forceinput.

    294 GitHub stars~3k tokensUpdated 2 mo ago
    Auto-check passed
  • Comfyui Node Lifecycle

    jtydhr88/comfyui-custom-node-skills

    ComfyUI node execution lifecycle - caching, fingerprintinputs/ISCHANGED, validateinputs/VALIDATEINPUTS, checklazystatus, execution order.

    294 GitHub stars~2.9k tokensUpdated 2 mo ago
    Auto-check passed
  • Comfyui Node Migration

    jtydhr88/comfyui-custom-node-skills

    ComfyUI V1 to V3 node migration - converting legacy nodes to the V3 API.

    294 GitHub stars~3.2k tokensUpdated 2 mo ago
    Auto-check passed

Questions about ComfyUI Frontend Extensions

What does ComfyUI Frontend Extensions do?

Guide to writing JavaScript extensions for the ComfyUI frontend from custom nodes, covering lifecycle hooks, widgets, sidebar tabs, commands, settings, toasts and dialogs. This skill shows how a custom node can extend the ComfyUI frontend with JavaScript. The quick start exports WEB_DIRECTORY from the node's Python package, pointing at a js folder, then adds a JavaScript file that imports app and calls registerExtension.

When should I use ComfyUI Frontend Extensions?

ComfyUI Frontend Extensions fits situations like: adding UI features to a ComfyUI custom node; creating a custom widget type for node inputs; registering a sidebar tab, command or setting from an extension; restoring node state when a saved graph loads.

How do I install ComfyUI Frontend Extensions in Claude Code?

Run `npx skills add jtydhr88/comfyui-custom-node-skills --skill comfyui-node-frontend -a claude-code`. Or copy the skill folder (plugins/comfyui-custom-nodes/skills/comfyui-node-frontend in jtydhr88/comfyui-custom-node-skills) into .claude/skills/comfyui-node-frontend in your project. Claude Code loads it when a task matches its description.

How do I install ComfyUI Frontend Extensions in Codex?

Run `npx skills add jtydhr88/comfyui-custom-node-skills --skill comfyui-node-frontend -a codex`. Or copy the skill folder (plugins/comfyui-custom-nodes/skills/comfyui-node-frontend in jtydhr88/comfyui-custom-node-skills) into .agents/skills/comfyui-node-frontend in your project. Codex loads it when a task matches its description.

Can I use ComfyUI Frontend Extensions in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add jtydhr88/comfyui-custom-node-skills --skill comfyui-node-frontend -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/comfyui-node-frontend, .gemini/skills/comfyui-node-frontend, .github/skills/comfyui-node-frontend and .opencode/skills/comfyui-node-frontend in your project.

What does ComfyUI Frontend Extensions need to run?

SKILL.md names no scripts, command-line tools or credentials: ComfyUI Frontend Extensions is instructions for the agent only. Our summary lists: A ComfyUI custom node package with a Python __init__.py; A running ComfyUI installation to load the extension.

Does ComfyUI Frontend Extensions access the network?

SKILL.md names 1 domain. In commands or code: github.com; the agent is likely to contact it when it follows the instructions. This is read from the text; nothing was executed.

Is ComfyUI Frontend Extensions safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does ComfyUI Frontend Extensions use?

ComfyUI Frontend Extensions is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does ComfyUI Frontend Extensions use?

About 3.7k tokens (SKILL.md is roughly 15k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to ComfyUI Frontend Extensions?

Skills that share tags, products or a category with ComfyUI Frontend Extensions: ComfyUI Custom Node Builder (ConstantineB6/comfy-pilot, 230 stars), Setup (guaardvark/guaardvark, 255 stars), AI Toolkit Trainer (artokun/comfyui-mcp, 795 stars) and Add Comfyui Node (Mooshieblob1/MooshieUI, 207 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains ComfyUI Frontend Extensions?

jtydhr88 (a GitHub user) maintains it in jtydhr88/comfyui-custom-node-skills, which has 294 GitHub stars. The repository holds 9 skills in this directory. The repository was last updated on July 27, 2026.

Source: jtydhr88/comfyui-custom-node-skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.