A desktop GUI for designing and generating ComfyUI custom nodes — without writing boilerplate.
You can visually configure your node's inputs, outputs, category, and flags. The app generates all the required Python code programmatically.
An integrated LLM assistant writes the actual node logic (execute() body) based on your description, with full multi-turn conversation history so you can iterate and see what was added when.
Preview your node visually to see something like what it will look like in ComfyUI.
View the code for the node.
| Tab | What it does |
|---|---|
| Node Settings | Internal name (snake_case), display name, category, pack folder toggle |
| Inputs | Add/edit/reorder input sockets and widgets with full type and config |
| Outputs | Add/edit/reorder output sockets |
| Advanced | OUTPUT_NODE, INPUT_NODE, VALIDATE_INPUTS, IS_CHANGED flags |
| Preview | Visual ComfyUI-style node preview — shows proposed AI changes as a live diff |
| Code | Editable Monaco Editor showing the full generated Python; locked while an AI proposal is pending |
| AI Assistant | Multi-turn LLM chat for generating or rewriting node logic |
- All nodes in a project export together as a single ComfyUI custom node pack
- Configure Pack Name (used as folder name —
ComfyUI_prefix recommended) and Project Display Name separately - Export preview shows the output file tree before you export
- Set a persistent Export Location (your
ComfyUI/custom_nodes/folder) for one-click export from the toolbar or Pack tab - Exported structure:
PackName/__init__.py+PackName/nodes/<node>.py+PackName/README.md
- Single button press — Export your nodes to a custom node pack.
- Import existing node packs — If a node pack uses the same layout/structure, it can be imported into the tool.
- INT / FLOAT — min, max, step, default, round
- STRING — single-line or multiline textarea
- COMBO — dropdown with a configurable list of options
- forceInput toggle — expose any widget type as a connector instead of an inline control
| Flag | Effect |
|---|---|
OUTPUT_NODE |
Node always executes; use for save/preview/side-effect nodes |
INPUT_NODE |
Marks node as an external data source |
VALIDATE_INPUTS |
Generates a validate_inputs() stub called before execute() |
IS_CHANGED: none |
Default ComfyUI caching — re-runs only when inputs change |
IS_CHANGED: always |
Forces re-execution every run (randomness, timestamps, live data) |
IS_CHANGED: hash |
Generates an MD5 hash of inputs; re-runs only when hash changes |
- Functionality Edit mode — LLM writes only the
execute()body; safe with weaker local models - Full Node mode — LLM rewrites the entire class structure (inputs, outputs, execute body)
- Multi-turn chat — full conversation history per node, per mode, persisted across sessions
- Configurable context window — control how many past messages are sent to the LLM
- Abort / cancel — stop generation mid-stream
- Proposal preview — proposed changes shown as a live diff in the Inputs/Outputs/Preview/Code tabs before accepting
- Proposal diff in Code tab — side-by-side Monaco diff view of current vs proposed code while a proposal is pending
- Rejected proposal log — when you reject an AI proposal, the rejected changes are recorded in the chat and included in subsequent LLM context so the model knows what was tried and refused
- Auto-retry on format / validation errors — if the LLM returns malformed JSON or invalid operations, the app automatically sends a correction prompt and retries once
- Tooltip / description enforcement — the system prompt and validation require all inputs and outputs to have a tooltip; invalid entries are flagged and retried
- Custom AI instructions — extra guidance appended to the system prompt, scoped to global / provider / model
- Favorite models — right-click any model pill in Settings → AI Providers to star it; favorites appear at the top in gold in both the settings list and the model dropdown in the AI Assistant tab
OpenAI, Anthropic (Claude), Google Gemini, Groq, xAI (Grok), OpenRouter, Ollama (local)
- API keys encrypted and stored locally via Electron
safeStorage— never sent anywhere except the provider's own API - Test connection button per provider
- Fetch available models from Ollama or Groq with one click
- Add custom model names for any provider
- Favorite models — right-click a model pill to star it; favorites shown at the top in gold, grouped separately from other models
- Ollama VRAM usage — when Ollama is the active provider, shows live VRAM usage for any models currently loaded in GPU memory
- Import from file — parse a single
.pyfile - Import from folder — recursively scans a ComfyUI pack folder, handles:
- Multi-file packs where classes are split across individual
.pyfiles - Cross-file class lookup (classes defined in separate files, imported via
__init__.py) - Utility inlining — relative imports (e.g.
from .utils import helper) are detected and their source is inlined into the imported execute body - Emoji and Unicode node names
- Multi-file packs where classes are split across individual
- Save and load
.cndproject files — design nodes across multiple sessions - Recent projects list (configurable count, can be disabled)
- Unsaved-changes guard on close, new, and open
- Resizable sidebar — drag the edge to adjust the node list width
- Drag-to-reorder nodes in the sidebar
- Duplicate / delete nodes with confirmation
- Per-type color overrides — customize the connection wire colors for any ComfyUI type
- Native OS dialogs for confirmations (not browser alerts)
- Keyboard shortcuts:
Ctrl+Ssave,Ctrl+Oopen,Ctrl+Nnew project
- Node.js 18 or newer — nodejs.org
- npm (comes with Node.js)
- Git — git-scm.com
You do not need Python, ComfyUI, or any other tools installed to run the designer itself.
Download and install Node.js from nodejs.org. Choose the LTS version.
Verify the install:
node --version
npm --version
git clone https://github.com/MNeMoNiCuZ/ComfyNodeDesigner.git
cd ComfyNodeDesignernpm installThis downloads all required packages into node_modules/. Only needed once (or after pulling new changes).
npm run devThe app opens automatically. Source code changes hot-reload.
npm run packageOutput goes to dist/:
- Windows →
.exeinstaller (NSIS, with directory choice) - macOS →
.dmg - Linux →
.AppImage
To build for a different platform you must run on that platform (or use CI).
- Click Add Node in the left sidebar (or the
+button at the top) - Fill in the Identity tab: internal name (snake_case), display name, category
- Go to Inputs → Add Input to add each input socket or widget
- Go to Outputs → Add Output to add each output socket
- Optionally configure Advanced flags
- Open Preview to see the visual node preview, or Code to see and edit the generated Python
- Open the Settings tab (gear icon, top right) and enter your API key for a provider
- Select the AI Assistant tab for your node
- Choose your provider and model
- Type a description of what the node should do
- Hit Send — the LLM writes the
execute()body (or full class in Full Node mode) - Review the proposal — a diff preview appears in the Inputs/Outputs tabs
- Click Accept to apply the changes, or keep chatting to refine
Point the Export Location (Pack tab or Settings) at your ComfyUI/custom_nodes/ folder, then:
- Click Export in the toolbar for one-click export to that path
- Or use Export Now in the Pack tab
The pack folder is created (or overwritten) automatically. Then restart ComfyUI.
- Click Import in the toolbar
- Choose From File (single
.py) or From Folder (full pack directory) - Detected nodes are added to the current project
| Shortcut | Action |
|---|---|
Ctrl+S |
Save project (prompts for path if new) |
Ctrl+O |
Open .cnd project file |
Ctrl+N |
New project |
API keys are encrypted and stored locally using Electron's safeStorage. They are never sent anywhere except to the provider's own API endpoint.
| Provider | Where to get an API key |
|---|---|
| OpenAI | platform.openai.com/api-keys |
| Anthropic | console.anthropic.com |
| Google Gemini | aistudio.google.com/app/apikey |
| Groq | console.groq.com/keys |
| xAI (Grok) | console.x.ai |
| OpenRouter | openrouter.ai/keys |
| Ollama (local) | No key needed — install Ollama and pull a model |
- Install Ollama from ollama.com
- Pull a model:
ollama pull llama3.3(or any code model, e.g.qwen2.5-coder) - In the app, open Settings → Ollama
- Click Fetch Models to load your installed models
- Select a model and start chatting — no key required
ComfyNodeDesigner/
├── src/
│ ├── main/ # Electron main process (Node.js)
│ │ ├── index.ts # Window creation and IPC registration
│ │ ├── ipc/
│ │ │ ├── fileHandlers.ts # Save/load/export/import — uses Electron dialogs + fs
│ │ │ └── llmHandlers.ts # All 7 LLM provider adapters with abort support
│ │ └── generators/
│ │ ├── codeGenerator.ts # Python code generation logic
│ │ └── nodeImporter.ts # Python node pack parser (folder + file import)
│ ├── preload/
│ │ └── index.ts # contextBridge — secure API surface for renderer
│ └── renderer/src/ # React UI
│ ├── App.tsx
│ ├── components/
│ │ ├── layout/ # TitleBar, NodePanel, NodeEditor
│ │ ├── tabs/ # Identity, Inputs, Outputs, Advanced, Preview, AI, Pack, Settings
│ │ ├── modals/ # InputEditModal, OutputEditModal, ExportModal, ImportModal
│ │ ├── shared/ # TypeBadge, TypeSelector, ExportToast, etc.
│ │ └── ui/ # shadcn/Radix UI primitives
│ ├── store/ # Zustand state (projectStore, settingsStore)
│ ├── types/ # TypeScript interfaces
│ └── lib/ # Utilities, ComfyUI type registry, node operations
- Electron 34 — desktop shell
- React 18 + TypeScript — UI
- electron-vite — build tooling
- TailwindCSS v3 — styling
- shadcn/ui (Radix UI) — component library
- Monaco Editor — code preview
- Zustand — state management
npm run dev # Start in development mode
npm run build # Production build (outputs to out/)
npm test # Run vitest tests
npm run package # Package as platform installer (dist/)Pull requests welcome. For major changes, open an issue first to discuss the direction.
- Fork the repo
- Create a feature branch:
git checkout -b feature/my-thing - Make your changes
- Run a build to confirm nothing is broken:
npm run build - Open a pull request
MIT — see LICENSE