ComfyUI-Drawer
A mobile-friendly modular UI platform for ComfyUI
Nodes (9)
Feature Demo
https://github.com/user-attachments/assets/a9ba848f-11eb-42f7-9fc8-31616ed82df5
Note: This demo includes third-party custom nodes that are not included with ComfyUI-Drawer.
What is ComfyUI-Drawer?
ComfyUI-Drawer turns complex ComfyUI workflows into compact, touch-friendly control panels.
Keep your node graph intact, expose only the parameters you actually want to touch, and manage outputs, model assets, masks, and parameter sweeps from one bottom drawer.
The drawer is modular, so it can host workflow controls, media management, model browsing, plotting tools, and custom extensions in one place.
Why Drawer?
On desktop, ComfyUI-Drawer adds a remote-control layer to the ComfyUI canvas: keep the graph open, but operate the controls, assets, and inspection tools you actually touch from one bottom drawer.
On mobile and small displays, that same drawer becomes the main working surface. It makes active creation practical by keeping parameter control, output review, model browsing, mask editing, prompt dictionaries, and XYZ sweeps within reach.
Unlike APP mode, Drawer is designed for editing, testing, and iterating on workflows without turning them into separate apps.
Installation
Via ComfyUI-Manager (Recommended)
Search for ComfyUI-Drawer in the ComfyUI-Manager install menu.
Manual Installation
cd ComfyUI/custom_nodes
git clone https://github.com/Kuroi961/ComfyUI-Drawer.git
pip install -r ComfyUI-Drawer/requirements.txt
Dependencies
requirements.txt lists the Python packages this extension installs directly. ComfyUI normally already provides Pillow and SQLite support, which Drawer uses for image thumbnails, media metadata, and the Gallery search index.
Video thumbnails and video/audio metadata use the external ffmpeg / ffprobe binaries when available. They are optional system tools, not Python packages; without them, images and model browsing still work, while video thumbnails fall back to a placeholder and some video/audio metadata may be unavailable.
Sample Workflows
<p align="left"> <img src="docs/sample.webp" width="50%"> </p>You can open ComfyUI-Drawer sample workflows from ComfyUI's template browser.
drawer-sample-animaโ A sample workflow that demonstrates the basic Drawer workflowdrawer-sample-anima-advancedโ A more practical workflow using external custom nodes. Additional models and nodes are required (rgthree-comfy,comfyui-impact-pack,comfyui-ppm,comfyui-kjnodes,comfyui-easy-use,seedvr2_videoupscaler)drawer-tutorial-deck-ja/drawer-tutorial-deck-en/drawer-tutorial-deck-zhโ Tutorials for displaying workflow nodes in Deck
Built-in Gadgets
In ComfyUI-Drawer, each tool that lives inside the drawer is called a gadget.
Deck
<p align="left"> <img src="docs/deck.webp" width="50%"> </p>A gadget for quick parameter control of your workflow.
Display Control:
Add markers to node or group titles to control what appears in Deck.
| Marker | Target | Effect |
|--------|--------|--------|
| ๐ | Node title | Shows that node's widgets on the Deck main screen |
| โก | Node or group title | Adds a bypass ON/OFF switch |
| [label] | Node or group title | Creates an exclusive bypass switch among items with the same label |
Nodes are sorted by Y position from top to bottom. Groups are sorted by X position from left to right.
Other behavior:
- Groups are always shown as sections if they contain at least one visible node
- Ungrouped nodes are collected at the end under Other
- A bottom-left button can show nodes that do not contain
๐
XYZ Plot
<p align="left"> <img src="docs/xyzplot.webp" width="50%"> </p>https://github.com/user-attachments/assets/dcb8cfd6-3a74-4cb3-8694-e9cd9c7f6282
A parameter sweep gadget familiar from Stable Diffusion web UI (A1111). Behavior is largely consistent with A1111.
No dedicated XYZ nodes or extra wiring are required; sweep the widgets and bypass states already present in the current workflow.
Basic features:
- Assign any widget from any node to the X/Y/Z axes for sequential generation
- Text widgets automatically use Prompt S/R (Search & Replace) mode
- Bypass axes โ use node ON/OFF, Deck group toggles, group switches, and node switches as sweep dimensions
- Zip mode โ pair two adjacent axes so they step in lock-step instead of producing a cartesian product (e.g. sweep
(model, lora)pairs together on X+Y) - Automatically generates a labeled grid composite image and saves it to output
Technical details:
| Feature | Details |
|---------|---------|
| Queue lock | During a sweep, app.queuePrompt is monkey-patched to block external queue submissions. It is restored after the sweep finishes |
| Seed pinning | A snapshot of all widget values is taken at sweep start. Before each iteration, the snapshot is restored, then axis values are applied on top |
| DrawerSeed integration | DrawerSeed randomization is executed once just before the sweep. During the sweep, window.__xyzSweepActive suppresses DrawerSeed's queue hook randomization |
| batch_size enforcement | Non-sweep batch_size widgets are forced to 1. control_after_generate is forced to fixed |
| Zip mode | A "Zip" checkbox between each axis pair locks them into lock-step iteration. X+Y zip with 3 values each โ 3 generations instead of 9. Mismatched lengths are padded with no-ops and flagged in preflight |
| Preflight validation | Widget type and value ranges are validated before the sweep starts; mismatches trigger a warning |
| Server disconnect detection | WebSocket status / reconnecting events are monitored, and the sweep is aborted immediately if the server disconnects |
| Workflow embedding | Embeds workflow JSON into composite images as PNG PngInfo or JPEG/WebP EXIF |
Gallery
<p align="left"> <img src="docs/gallery.webp" width="50%"> <img src="docs/gallery2.webp" width="25%"> </p>A gadget for browsing media and folders under the output, input, and temp directories.
- Folder navigation with breadcrumbs, sorting by name/date/size
- File rename, move (D&D / batch selection), and delete
- Filename search works without an index; prompt, workflow, node type, and node title metadata search use an explicitly created SQLite search index
- Search supports quoted phrases, space-separated AND terms, and NOT terms with
-wordor-"quoted phrase" - Node type-scoped search can target values from a specific node type with syntax such as
type:CLIPTextEncode[white hair -night]. The[...]part acts like a virtual search box for values inside that node type, using the same phrase / AND / NOT rules as the main search field - Node title-scoped search is also available with syntax such as
title:My Prompt Node[school uniform]ortitle:"Prompt A"[blue sky]. The title part matches node titles, and the[...]part searches values inside matching titled nodes - Third-party custom metadata can be searched when a custom node registers a Drawer index contributor. Custom fields use
namespace[value]ornamespace:key[value], for examplemyPlugin:tags[black hair] - Search filters include target field, date range, and file size, with a compact mobile-friendly two-row search toolbar
- Node type, user dictionary, Danbooru dictionary, and registered custom metadata key autocomplete are available in the Gallery search field
- New folder creation, folder move, and folder delete
Model Viewer
<p align="left"> <img src="docs/modelviewer.webp" width="25%"> </p>A gadget for browsing models and folders under ComfyUI's models directory and model paths added through extra_model_paths.yaml.
- Supports all model types, such as checkpoints, loras, vae, embeddings, controlnet, upscale_models, and more
- CivitAI sync โ Fetch metadata and preview images by SHA256 hash matching, with
.red/.comfallback - Node matching โ From the info card, apply a model to compatible loader nodes in the current workflow. This scans all nodes, including subgraphs, Combo Clone widgets, and connected DrawerControls
- Trigger words โ CivitAI
trainedWordsare shown automatically. Custom words can also be added for LoRA models - Sidecar thumbnail support, with output-image picker and delete actions
- Video previews (
.mp4/.webm) in the grid and info card - Per-model user memos persisted in
.drawer.json
Workflow Utilities
<p align="left"> <img src="docs/others.webp" width="50%"> </p>User Dictionaries & Wildcards
A built-in dictionary service for prompt autocomplete.
https://github.com/user-attachments/assets/34237d5e-cd92-4a8e-a638-cb6d98256536
- Danbooru tag dictionary โ Tag database with usage counts (CSV)
- User dictionaries โ Create custom tag โ insert text mappings
- Wildcards โ Use
__name__syntax to randomly select one line from a list - CSV / TXT import โ Import existing tag files
- Comment syntax โ Use
//,#, and/* */to comment out parts of prompts - No nodes required โ Wildcards and comment stripping are applied automatically when the prompt is queued
Dictionaries can be created, edited, and toggled from the Settings panel. You do not need to add wildcard, dictionary, or preprocessing nodes to the workflow. Normal prompt nodes, text passed through DrawerControls, and other string widgets can use comment stripping and wildcard expansion automatically when ComfyUI queues the prompt.
Prompt processing behavior:
__name__expands to one line from an enabled wildcard dictionary with the same name- Expansion is based on
seed,noise_seed, orseed_valuein the workflow. If a seed is found, the same seed produces the same expansion. If no seed is found, normal random selection is used - Comments are removed from the execution prompt, but preserved in the workflow metadata embedded in output images
/* ... */is a block comment,// ...is a line comment, and# ...at the beginning of a line is also treated as a line comment- Escaped markers such as
\#and\/are treated as literal characters, not comment starts
CSV / TXT import format:
User dictionaries are imported as CSV. Wildcards are imported as TXT. CSV files require a header row.
tag,insert_text
sky,"blue sky, clouds"
masterpiece,"masterpiece, best quality"
tagis the name shown in autocompleteinsert_textis the text inserted when selected. If empty, thetagitself is used- Values containing commas should be quoted like normal CSV
Wildcard TXT files use one candidate per line. The imported filename, or the dictionary name set in Settings, becomes the name used in __name__.
blue sky, sunlight
night city, neon lights
soft backlight, floating particles
- Empty lines are ignored
- Lines beginning with
#or//are not used as wildcard candidates - Recursive wildcard expansion is not performed. If a candidate contains
__other__, that text remains as-is - Wildcards inside comments are not expanded
Mask Editor
A fullscreen mask editor available from image context menus. It saves generated masks under input/drawer_masks and can apply them directly to LoadImageMask nodes.
Shared UI System
Context Menu
A right-click / long-press menu. It supports opening media in a new tab, sending images to LoadImage / LoadImageMask, opening media as a workflow, downloading, and gadget-specific custom menu actions.
Lightbox
A fullscreen media viewer for images, videos, and audio. It opens from Gallery, Deck, XYZ Plot, and shared media cards.
- Keyboard navigation (โโ / A/D), swipe, and previous/next buttons
- Click the current image, or use the context menu, to open media in a new tab
- Images can be dragged from the lightbox onto the ComfyUI canvas
- Context menu support inside the lightbox
Popups & Dialogs
Provides showAlert, showConfirm, showPrompt, and showDialog.
File Picker
A modal picker for media selection. It supports image, video, and audio selection with thumbnail folder navigation.
Multi-language Support
Supports English, Japanese, and Chinese (Simplified). The language automatically follows ComfyUI's Settings > Locale preference.
Drawer Nodes
9 utility nodes with dedicated Deck-side UI support.
| Node | Description |
|------|-------------|
| DrawerSeed | Seed node with randomize / fixed modes |
| DrawerControls1 / 4 / 8 / 12 | Compact parameter hubs. Only connected outputs appear as Deck controls: int, float, combo, bool, or string. Use string \| Label for single-line text and string \| Label \| multiline for multiline text. Combo options are read from the connected target widget |
| DrawerConcat | Joins variable-length text inputs with a configurable delimiter |
| DrawerSize | Resolution presets for landscape, portrait, and square outputs |
| DrawerSwitch | Universal A/B switch for any data type. If B is connected and non-empty, B is returned; otherwise A is returned. Uses ComfyUI V3 API lazy evaluation so the unnecessary branch is not executed |
| DrawerSwitchChain | Variable-length fallback chain. The last connected non-empty value wins |
Developer / Agent Notes
ComfyUI-Drawer is designed as an extensible platform. You can create self-contained gadgets in a single file:
- Copy docs/gadget-template.js
- Place it in any
custom_nodes/*/web/js/folder. It does not have to be inside ComfyUI-Drawer itself - Modify the class and restart ComfyUI
import { app } from "../../../scripts/app.js";
app.registerExtension({
name: "Comfy.Drawer.MyGadget",
async setup() {
const drawer = window.ComfyDrawer ?? await new Promise(resolve =>
window.addEventListener('comfy-drawer:ready', e => resolve(e.detail), { once: true })
);
const { GadgetBase } = drawer;
class MyGadget extends GadgetBase {
constructor() {
super('my-gadget', { label: 'My Gadget', icon: '๐ง', order: 10 });
}
onMount(container, bus, bridge) {
container.innerHTML = '<p>Hello World</p>';
}
}
drawer.registerGadget(new MyGadget());
},
});
window.ComfyDrawerexposes services such asGadgetBase,bus,bridge,settings, anddict- CSS can be injected with a
<style>tag. Scoping with@layer gadget-<id>is recommended - The only external import needed is
app.js; gadgets do not need to depend on Drawer internals - Python extensions can register Gallery metadata providers, search index contributors, metadata panel contributors, and dictionary providers. This lets existing custom metadata become searchable and visible in Drawer without forcing a Drawer-specific storage format
See GADGET_API.md for the complete API reference.
| Document | Description | |----------|-------------| | docs/USER_GUIDE.md | Detailed user guide beyond the README | | ARCHITECTURE.md | Platform architecture, module responsibilities, and design decisions | | CONVENTIONS.md | Code style, CSS scoping, and naming conventions | | GADGET_API.md | Gadget development API reference |
About This Project
ComfyUI-Drawer is 100% coded by AI under human direction, review, and testing.
License
ComfyUI-Drawer uses split licensing:
- Implementation: GPL-3.0-or-later
- Public specification docs (
ARCHITECTURE.md,CONVENTIONS.md,GADGET_API.md): CC0-1.0 - Gadget template (
docs/gadget-template.js): MIT
ยฉ 2026 Kuroi