A curated collection of enhancement utilities for ComfyUI, combining and improving features from several community packages into a single, well-organized package built on the V3 API (comfy_api).
Full Subgraph Support -- Every feature in this package works inside subgraphs. Graph arrangement, node navigation, execution profiling, and running-node highlights all handle nested subgraphs correctly. None of the original packages these features were drawn from support subgraphs.
Nodes 2.0 Compatible -- Every feature works in both the legacy LiteGraph canvas renderer and the new Nodes 2.0 Vue renderer. Profiling badges, graph arrangement, node navigation, resource monitoring, and all nodes function correctly in either mode.
Real-time system stats displayed as horizontal colored bars in the ComfyUI menu bar.
| Metric | Color | Display |
|---|---|---|
| CPU | Amber | Utilization % |
| RAM | Green | Used / total (tooltip shows bytes) |
| Disk | Muted purple | Usage for a selected partition |
| GPU | Blue | Utilization % (NVIDIA only) |
| VRAM | Teal | Used / total, max-used tracking in tooltip |
| Temp | Green-to-red gradient | GPU temperature in degrees |
| Power | Red-orange | Current wattage (bar fill = % of TDP) |
Historical graphs -- hover any bar for a single-metric sparkline popup. Click any bar to pin a grid showing all metrics at once. Click again or click outside to dismiss.
Electricity cost -- session power consumption is tracked and displayed on the power bar tooltip and graph popup. Configure your electricity rate and currency symbol in settings.
History persists through browser refresh -- data is stored server-side in memory. Choose a display window (5 / 10 / 20 / 30 min, 1 hr, or Unlimited). Right-click the monitor bars to clear history.
GPU support:
- NVIDIA GPUs via optional
pynvml - Graceful fallback if no NVIDIA GPU or
pynvmlnot installed - Respects
CUDA_VISIBLE_DEVICES-- only monitors GPUs ComfyUI can use - Safe ZLUDA detection (won't crash on AMD GPUs faking CUDA)
Displays execution time badges on nodes after a workflow runs.
- Per-node timing -- a small badge above each node shows how long it took to execute (e.g.,
1.23sor456ms) - Subgraph totals -- subgraph container nodes show the aggregated time of all their internal nodes, updating live as children complete
- Persistent data -- profiling badges survive navigating into/out of subgraphs, switching between workflows, and browser refreshes. Data is retained server-side and restored automatically on page load. Data only clears when the workflow is run again.
Badges also display inside subgraphs:
Enabled by default. Toggle in ComfyUI Settings: Node Profiler - Enabled.
To access profiling data programmatically within your workflow (e.g., for logging or conditional logic), use the Profiler Timing node. It can read the execution time of any node by linking to it or specifying its ID.
Right-click canvas (added to the bottom of the context menu)
| Option | Description |
|---|---|
| Go to Node | Hierarchical submenu listing all nodes grouped by type. Click any node to center the viewport on it. Supports subgraph navigation -- clicking a node inside a subgraph will navigate into that subgraph first. |
| Follow Execution | Toggle that auto-pans the canvas to track the currently executing node in real time. |
| Show Executing Node | One-shot jump to whichever node is currently running (only appears during execution). |
Additionally draws a green border around the currently executing node.
Right-click canvas > Arrange
Multiple auto-layout algorithms for organizing your workflow, all with full group and subgraph support:
| Option | Description |
|---|---|
| Center Graph (shift to 0,0) | Shifts all nodes and groups so the graph is centered at the origin. Useful when navigating between subgraphs leaves you lost in empty space. |
| Quick (column aligned) | Fast column-based layout with right-aligned nodes and barycenter sorting for reduced edge crossings. No external library needed. |
| Smart (dagre) | Sugiyama layered layout via dagre.js. Good balance of quality and speed. |
| Advanced (ELK) | Port-aware Sugiyama layout via the Eclipse Layout Kernel. Models each input/output slot as a port for optimal edge routing and crossing minimization. Best layout quality. |
Before:
After:
| Quick (column aligned) | Smart (dagre) | Advanced (ELK) |
![]() |
![]() |
![]() |
All layout algorithms:
- Respect groups -- nodes inside groups are arranged within their group first, then groups are arranged as units
- Work in subgraphs -- arranges only the graph level you're currently viewing
- Handle disconnected nodes -- nodes with no connections are laid out in a compact grid below the main graph
- Flatten nested groups -- nested groups are treated as part of their outermost parent
Settings (ComfyUI Settings panel):
| Setting | Default | Description |
|---|---|---|
| Flow direction | LR | Left-to-Right or Top-to-Bottom. Affects Dagre and ELK. |
| Node spacing | 50 | Gap between nodes in the same rank/column. |
| Rank spacing | 80 | Gap between ranks (columns or rows). |
| Group padding | 30 | Padding inside groups around the arranged nodes. |
Plays an audio file when execution reaches this node. Useful for alerting you when a long workflow completes.
| Input | Type | Description |
|---|---|---|
| any | Any (passthrough) | Connect any output to trigger the sound. Passed through unchanged. |
| mode | Combo | always or on empty queue (only plays when the queue finishes). |
| volume | Float | Playback volume (0.0 - 1.0). |
| file | String | Sound file name (from assets/) or a full URL. Default: notify.mp3. |
| Output | Type | Description |
|---|---|---|
| passthrough | Same as input | The input value, passed through unchanged. |
Sends a browser notification when execution reaches this node. The browser will request notification permission when the node is first added to the graph.
| Input | Type | Description |
|---|---|---|
| message | String | The notification body text. |
| any | Any (passthrough) | Connect any output to trigger the notification. Passed through unchanged. |
| mode | Combo | always or on empty queue. |
| Output | Type | Description |
|---|---|---|
| passthrough | Same as input | The input value, passed through unchanged. |
Reads execution timing data from the profiler and outputs it as float values. Wire inline via the pass-through to guarantee execution order.
| Input | Type | Description |
|---|---|---|
| any | Any (passthrough) | Connect any output to place this node inline in the workflow. Data passes through unchanged. |
| node_link | Any (optional) | Connect any output from a node to measure that node's execution time. The data itself is ignored. |
| node_ids | String (optional) | Comma-separated node IDs to look up (e.g. 43,32:234,54). Plain IDs resolve relative to the current subgraph first, then root. Subgraph container IDs return the total of all nodes inside. |
| Output | Type | Description |
|---|---|---|
| passthrough | Same as input | The any input forwarded unchanged (type-matched). |
| elapsed | Float | Wall-clock seconds since execution started. Unique to each instance based on where it sits in the workflow. |
| node_time | Float | Execution time in seconds for the resolved node(s). Summed if multiple IDs are provided. Returns 0.0 for cached or unresolved nodes. |
ID resolution order (for plain IDs like 54 when the node is inside subgraph 123):
- Same subgraph level:
123:54 - Nested child:
123:*:54 - Root level:
54 - If the resolved ID is a subgraph container, returns the sum of all nodes inside it
Both node_link and node_ids are additive -- their resolved times are summed together.
Category: image | Node: Load Image (With Subfolders)
An enhanced image loader that recursively scans the input directory for images, including all subfolders. Also extracts embedded metadata from PNG and WebP files.
| Input | Type | Description |
|---|---|---|
| image | Combo (with upload) | Select an image from the input directory. Subfolders are fully supported and shown as subfolder/filename.png. |
| Output | Type | Description |
|---|---|---|
| image | IMAGE | The loaded image tensor. Supports multi-frame (GIF, APNG, TIFF), 16-bit, and palette transparency. |
| mask | MASK | Alpha mask (or zeros if no alpha channel). |
| prompt | STRING | Embedded prompt metadata as JSON (empty {} if none found). |
| metadata | STRING | Full embedded metadata as JSON (PNG text chunks, WebP EXIF, JPEG EXIF). |
Improvements over other image loaders:
- Recursive subfolder scanning with
os.walk - Content-type filtering -- only shows actual image files (uses ComfyUI's MIME-type detection)
- Truncated image recovery -- uses
node_helpers.pillow()for resilient loading - Multi-frame support -- handles animated GIF/APNG, multi-page TIFF, MPO format
- 16-bit image support -- properly normalizes
Imode images - Palette transparency -- handles
Pmode images with transparency info - Metadata extraction -- PNG text chunks, WebP EXIF (via piexif), JPEG EXIF
- SHA-256 caching -- only re-executes when the file on disk actually changes
- Excludes system files (
Thumbs.db,.DS_Store,desktop.ini) and dot-folders
Search for "Enhancement Utils" in the ComfyUI Manager.
Clone the repository into your custom_nodes directory:
cd ComfyUI/custom_nodes
git clone https://github.com/phazei/ComfyUI-Enhancement-Utils.gitInstall dependencies:
pip install -r requirements.txtFor NVIDIA GPU monitoring (optional):
pip install pynvml| Package | Required | Purpose |
|---|---|---|
psutil |
Yes | CPU, RAM, and disk monitoring |
piexif |
Yes | WebP EXIF metadata extraction |
pynvml |
Optional | NVIDIA GPU monitoring (graceful fallback if missing) |
Pillow |
Yes (bundled with ComfyUI) | Image loading |
torch, numpy |
Yes (bundled with ComfyUI) | Tensor operations |
Vendored JavaScript libraries (no npm/build step required):
- dagre 0.8.5 (~284KB) -- Sugiyama layout algorithm
- elkjs 0.11.1 (~1.5MB) -- Eclipse Layout Kernel
ComfyUI-Enhancement-Utils/
├── __init__.py # V3 entrypoint (comfy_entrypoint)
├── pyproject.toml # Package metadata
├── LICENSE # MIT
│
├── nodes/
│ ├── play_sound.py # PlaySound node
│ ├── system_notification.py # SystemNotification node
│ ├── image_load_subfolders.py # ImageLoadWithSubfolders node
│ └── profiler_timing.py # ProfilerTiming node
│
├── monitor/
│ ├── collector.py # Background stats polling thread
│ ├── gpu.py # NVIDIA GPU abstraction layer
│ ├── hardware.py # CPU/RAM/Disk stats via psutil
│ └── routes.py # HTTP API endpoints
│
├── profiler/
│ ├── __init__.py # Module setup, triggers hooks on import
│ ├── hooks.py # Monkey-patches for execution timing
│ └── routes.py # HTTP API endpoint for profiler results
│
├── src/ # Build source (not served by ComfyUI)
│ ├── nodeProfilerBadge.ts # Vue-aware profiler badge (Nodes 2.0 compatible)
│ ├── vite.config.ts # Vite build config
│ └── package.json # Build dependencies
│
└── js/ # Served by ComfyUI (WEB_DIRECTORY = "./js")
├── utils.js # Shared subgraph/exec-ID utilities
├── graphArrange.js # Graph layout algorithms + menu
├── nodeNavigation.js # Go to Node, Follow Execution
├── nodeProfiler.js # Execution time badges (both renderers)
├── playSound.js # PlaySound client handler
├── systemNotification.js # Browser Notification handler
├── resourceMonitor.js # Monitor UI (bars, settings, cost tracking)
├── resourceMonitorGraph.js # Historical graph popup (Canvas 2D)
├── resourceMonitor.css # Monitor + popup + context menu styling
├── assets/notify.mp3 # Default notification sound
├── built/ # Vite build output (for future use)
└── lib/
├── dagre.min.js # Vendored dagre library
└── elk.bundled.min.js # Vendored ELK library
All Python nodes use the V3 schema (comfy_api.latest) with io.ComfyNode, define_schema(), and io.NodeOutput. Most frontend extensions are plain JavaScript (no build step). Extensions requiring Vue reactivity for Nodes 2.0 compatibility are built from TypeScript source in src/ using Vite.
This package combines and improves upon work from:
-
ComfyUI-Custom-Scripts by pythongosssss -- Original source for PlaySound, SystemNotification, Node Navigation (Go to Node, Follow Execution), and Graph Arrange (Float Left/Right). These features have been rewritten for the V3 API, with improvements including proper
MatchTypefor wildcard passthrough (replacing theAnyType(str)hack), barycenter sorting for reduced edge crossings, and disconnected node handling. -
ComfyUI-Crystools by crystian -- Original source for the Resource Monitor and ImageLoadWithMetadata. The monitor has been rewritten with fixes for thread deadlocks (
asyncio.run()in thread), GPU crash safety (ZLUDA detection,UnicodeDecodeErroron GPU names), fast startup (platform-native CPU detection instead ofpy-cpuinfo), andCUDA_VISIBLE_DEVICESsupport. The image loader combines Crystools' subfolder scanning with ComfyUI's built-in robustness (multi-frame, truncated image recovery, palette transparency). -
dagre -- JavaScript library for directed graph layout using the Sugiyama algorithm. MIT licensed.
-
elkjs -- JavaScript port of the Eclipse Layout Kernel, providing advanced port-aware layered layout. EPL-2.0 licensed.
MIT License. See LICENSE for details.










