A custom node pack for ComfyUI that provides an intuitive prompt drafting, saving, loading and management system with wildcard support.
- Dual Prompt Drafter: Main node with separate positive (green) and negative (red) prompt fields
- Dual Prompts + Loaded Loras: Extended dual prompt node with LoRA management and LoRA Manager integration
- Single Prompt Drafter: Flexible single prompt field (silver) for either positive or negative use
- Wildcard Node: Create and manage wildcard value lists with multiple output modes
- Prompt Combiner: Combine multiple strings with smart comma handling (up to 25 inputs)
- Prompt De-Dupe: Remove duplicate tags and phrases from prompts with intelligent conflict resolution
- Dynamic Wildcard Ports: Automatically creates input ports based on
{wildcard_name}patterns in your text - Save/Load System: Save and load prompt combinations and wildcards as JSON files
- Add Wildcard Buttons: Convenient buttons to insert numbered wildcard placeholders (
{wildcard_01},{wildcard_02}, etc.) - Prefix/Suffix Support: Chain prompts together with optional prefix and suffix inputs
- Smart Comma Handling: Automatically ensures proper
,separation without double commas - Raw Text Outputs: Access unprocessed text field values separately from prefix/suffix processed outputs
cd ComfyUI/custom_nodes
git clone https://github.com/Carasibana/ComfyUI-PromptDrafter.gitTo update to the latest version:
cd ComfyUI/custom_nodes/ComfyUI-PromptDrafter
git pullNote: Your saved prompts and wildcards in the saved/ folder are preserved during updates.
- Download the repository as a ZIP file
- Extract to
ComfyUI/custom_nodes/ComfyUI-PromptDrafter - Restart ComfyUI
Note: When updating manually, your existing saved/ folder will be preserved if you don't overwrite it during extraction.
The main node for creating prompt combinations with both positive and negative prompts.
Inputs:
positive_prompt(text): Your positive prompt with green border- "Add Wildcard to Prompt" button below to insert numbered wildcards
negative_prompt(text): Your negative prompt with red border- "Add Wildcard to Prompt" button below to insert numbered wildcards
positive_prefix(optional string): Text to prepend to positive promptpositive_suffix(optional string): Text to append to positive promptnegative_prefix(optional string): Text to prepend to negative promptnegative_suffix(optional string): Text to append to negative promptprompt_name(string): Name for saving/loadingload_prompt(dropdown): Select a saved prompt to load- Dynamic
wildcard_*inputs: Automatically created based on wildcards in your text
Outputs:
positive_prompt(string): Processed positive promptnegative_prompt(string): Processed negative prompt
Collapse/Expand: Click the arrow button (► or ▼) on the top-right of each text field to collapse or expand it. When collapsed, the text fields shrink to show only the first line, saving vertical space in your workflow. The "Add Wildcard" buttons are automatically hidden when collapsed to prevent overlapping. Collapse one field independently without affecting the other.
Extended dual prompt node with built-in LoRA management and LoRA Manager integration. Perfect for workflows where you want to save and load LoRA configurations alongside your prompts.
Inputs:
positive_prompt(text): Your positive prompt with green bordernegative_prompt(text): Your negative prompt with red borderlora_string(text): LoRA string in<lora:name:strength>format (widget or wired from LoRA Manager)push_lora_on_load(boolean, default: False): Enable to push saved LoRA state to a connected LoRA Manager node on prompt loadpositive_prefix,positive_suffix,negative_prefix,negative_suffix(optional strings): Prefix/suffix modifiersprompt_name(string): Name for saving/loading the prompt and LoRA combinationload_prompt(dropdown): Select a saved prompt+LoRA combination to load- Dynamic
wildcard_*inputs: Automatically created based on wildcards in your text
Outputs:
positive_prompt(string): Processed positive promptnegative_prompt(string): Processed negative promptloaded_loras(string): The LoRA string for reference or logginglora_stack(LORA_STACK): Parsed LoRA stack compatible with LoRA Manager nodes
Features:
- Save and load prompt+LoRA combinations as a unit
- Supports all wildcard features of the standard Dual Prompt node
- LoRA Manager Integration: When
push_lora_on_loadis enabled and a LoRA Manager node's 'loaded_lora's' output is connected to thelora_stringtext field's input:- Load Phase: Saved LoRA state is pushed upstream to the connected LoRA Manager node
- Modification Phase: Changes made in the LoRA Manager are captured when you run your workflow
- Save Phase: Updated LoRA configuration flows back into this node and can be re-saved
- This allows you to manage LoRAs in the LoRA Manager node while keeping the prompt+LoRA combination saved as a unit
A flexible single prompt node that can be used for either positive or negative prompts.
Inputs:
prompt(text): Your prompt with silver/neutral border- "Add Wildcard to Prompt" button below to insert numbered wildcards
prefix(optional string): Text to prependsuffix(optional string): Text to appendprompt_name(string): Name for saving/loadingload_prompt(dropdown): Select a saved prompt to load- Dynamic
wildcard_*inputs: Automatically created based on wildcards in your text
Outputs:
prompt(string): Processed prompt
Create and manage lists of values that can be randomly or sequentially selected.
Inputs:
wildcard_values(text): Values separated by newline, comma, or|output_mode(dropdown): How to select/output valuesrandom: Randomly select one valuesequential: Cycle through values in orderfixed: Use a specific indexdynamic_prompts: Output in{opt1|opt2|opt3}format for Dynamic Prompts compatibilitylist (csv): Output as comma-separated list
fixed_index(int): Index to use when mode is "fixed"wildcard_name(string): Name for saving/loadingload_wildcard(dropdown): Select a saved wildcard to load
Outputs:
wildcard_value(string): The selected or formatted value
A utility node for combining multiple strings with smart comma handling. Perfect for building complex prompts from multiple sources.
Inputs:
input_count(int): Number of inputs to show (2-25, default: 2)string_1throughstring_25(optional strings): Strings to combine- Only the number of inputs specified by
input_countare visible
- Only the number of inputs specified by
Outputs:
combined(string): All non-empty inputs combined with,separator
Features:
- Smart comma handling: Automatically adds
,between parts without creating double commas - Flexible input count: Show only the inputs you need (2-25)
- Ignores empty inputs: Blank or unconnected inputs are skipped
- Clean output: No trailing commas or extra spaces
Example:
- Input 1:
"masterpiece, best quality," - Input 2:
"portrait of a woman" - Input 3:
", detailed eyes" - Output:
"masterpiece, best quality, portrait of a woman, detailed eyes"
An intelligent de-duplication node that removes duplicate tags and phrases from prompts while intelligently resolving conflicts in weights and formatting.
Inputs:
input_string(text): The prompt string to de-duplicateforce_underscores(boolean, default: False): Replace spaces with_in tags onlyprose_threshold(int 1-20, default: 4): Word count threshold above which text is classified as proseprefer_specified_weights(boolean, default: True): Explicit weights beat implicit 1.0 valuesremove_spaces_around_commas(boolean, default: True): Normalize comma and semicolon spacing
Outputs:
cleaned_string(string): The de-duplicated promptremoved_items(string): Log of all duplicates and merges performedduplicate_count(int): Number of duplicates resolved
Features:
- Intelligent tag matching: Identifies duplicate Booru tags, natural language prose, and weighted expressions
- Weight conflict resolution: Automatically resolves conflicts between explicit weights (
:1.2) and implicit weights - Grouped bracket handling: Intelligently de-groups complex expressions when weights conflict
- Prose scanning: Finds tags embedded in natural language sentences and consolidates them
- Zone-based processing: Supports
BREAKandANDkeywords to process independent prompt zones - Special syntax protection: Preserves wildcards, LoRA references, prompt scheduling syntax, and nested brackets
- Detailed logging: Full console output showing all merges, consumed tags, and structural changes
- Underscore preference: Remembers and prefers underscores when encountered in any duplicate instance
Example:
Input: "blue_eyes, tall, blonde hair, blue eyes, dress, (blue eyes:1.2)"
Output: "blue_eyes, tall, blonde hair, dress, (blue_eyes:1.2)"
The De-Dupe node is especially useful when:
- Combining multiple prompt templates
- Working with stacked LoRAs that each add similar tags
- Building complex multi-concept prompts
- Cleaning up prompts before final generation
Type {wildcard_name} anywhere in your prompt text to create a wildcard placeholder. The node will automatically create an input port named wildcard_name that you can connect to a Wildcard node.
Example:
masterpiece, best quality, {wildcard_subject}, {wildcard_lighting}
This creates two input ports: wildcard_subject and wildcard_lighting.
The Wildcard node accepts values in multiple formats:
Newline separated:
blonde hair
brunette hair
red hair
Comma separated:
blonde hair, brunette hair, red hair
Pipe separated:
blonde hair | brunette hair | red hair
Use parentheses () or curly braces {} to group values that contain delimiters:
(red, green), blue, orange
Results in: ["(red, green)", "blue", "orange"]
{warm|cool}, neutral, {bright|dark}
Results in: ["{warm|cool}", "neutral", "{bright|dark}"]
This is useful for creating nested wildcard lists or preserving Dynamic Prompts syntax within values.
- Enter a name in the
prompt_namefield - Click the "Save Prompt" button
- The prompt is saved as a JSON file in the
saved/folder
- Select a prompt from the
load_promptdropdown - The prompt text fields will be populated with the saved values
Saved files are stored in:
saved/dual_prompts/- Dual prompt combinationssaved/single_prompts/- Single promptssaved/wildcards/- Wildcard lists
Edit config.json to customize save paths:
{
"save_paths": {
"dual_prompts": "saved/dual_prompts",
"single_prompts": "saved/single_prompts",
"wildcards": "saved/wildcards"
},
"settings": {
"auto_save": false,
"default_wildcard_mode": "random"
}
}- Add a Dual Prompt Drafter node
- Type your positive prompt:
masterpiece, {wildcard_style}, {wildcard_subject} - Type your negative prompt:
blurry, low quality - Add two Wildcard nodes
- Connect them to the automatically created
wildcard_styleandwildcard_subjectports - Fill in the wildcard values
- Connect the outputs to your CLIP Text Encode nodes
The pack comes with example saved prompts and wildcards:
Dual Prompts:
portrait_base- Basic portrait prompt templateanime_style- Anime-style prompt template
Single Prompts:
quality_tags- Common quality boosting tagsnegative_base- Common negative prompt tags
Wildcards:
hair_colors- Various hair colorseye_colors- Various eye colorslighting_styles- Different lighting setupsart_styles- Various art styles
- ComfyUI (latest version recommended)
- Works with Dynamic Prompts extension (use
dynamic_promptsoutput mode) - Dual Prompts + Loaded Loras node integrates with ComfyUI-Lora-Manager for bidirectional LoRA state management
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE file for details.
- Added: Pack icon - Added
icon-promptdrafter.svgto theassets/folder and referenced it inpyproject.tomlso the pack displays its icon in the ComfyUI registry- Fixed malformed icon URL in
pyproject.toml(ComfyUI-ComfyUI-PromptDrafter→ComfyUI-PromptDrafter)
- Fixed malformed icon URL in
- Bugfix: Prompt De-Dupe Node - Fixed
TypeError: can't access property "readOnly", inputEl is undefinedcrash on startup caused by a ComfyUI update that changed howComfyWidgets["STRING"]initialises the backing textarea element- Widget styling (
readOnly,opacity,fontSize,fontFamily,border,placeholder) is now applied conditionally, guarded by a null check oninputEl - The De-Dupe preview widget continues to function correctly; only the visual styling is skipped if
inputElis not yet available
- Widget styling (
- Refactor: Node namespace standardisation - All nodes now use a consistent
Name_PromptDrafterinternal ID scheme to prevent collisions with other ComfyUI custom node packs- New registration keys:
Dual_PromptDrafter,DualLora_PromptDrafter,Single_PromptDrafter,Wildcard_PromptDrafter,Combiner_PromptDrafter,DeDupe_PromptDrafter - Old keys are registered as deprecated aliases so existing saved workflows load without any changes required
- Deprecated aliases are hidden from the Add Node menu — only the new keys appear when searching
- Display names are unchanged
- New registration keys:
- NEW: Raw Text Outputs - All prompt drafter nodes now output raw, unprocessed text field values
- Dual Prompt Drafter: Added
positive_rawandnegative_rawoutputs - Dual Prompts + Loaded Loras: Added
positive_rawandnegative_rawoutputs - Single Prompt Drafter: Added
rawoutput - Raw outputs contain text field values with wildcard substitution but without prefix/suffix appending
- Allows downstream nodes to access original prompt text separately from prefix/suffix processing
- Dual Prompt Drafter: Added
- Bugfix: Dual Prompts + Loaded Loras Node -
lora_stackoutput now resolves full relative paths for LoRA files- Previously the stack contained only the bare filename (e.g.
my-lora-name-...) without subfolder or extension - Now searches ComfyUI's registered lora folders via
folder_paths.get_filename_list("loras")to resolve the full relative path (e.g.SubfolderA\\SubfolderB\\my-lora-name.safetensors) - Case-insensitive stem matching so capitalisation differences between the tag name and filename are handled gracefully
- Falls back to the bare name with a console warning if no matching file is found, so the stack is still populated
- Previously the stack contained only the bare filename (e.g.
- NEW: Dual Prompts - PromptDrafter + Loaded Loras Node - Extended dual prompt node with LoRA management
- Save and load LoRA configurations alongside prompt combinations
- Bi-directional LoRA state sync with LoRA Manager nodes
push_lora_on_loadoption to automatically push saved LoRAs to connected LoRA Manager on prompt load- Outputs parsed LORA_STACK for seamless LoRA Manager integration
- Supports all wildcard features of the standard Dual Prompt node
- Bugfix: Prompt De-Dupe Node - Fixed LoRA duplicate detection failing when LoRA tags had no comma separator between them
- Tokenizer now tracks angle-bracket depth (
</>) so adjacent LoRA tags like<lora:A:1.0><lora:A:1.1>are correctly split into separate segments - Added dedicated
_resolve_lora_duplicatespass (runs before tag deduplication) that groups LoRA segments by model name and keeps the one with the highest weight - Added
_extract_lora_nameand_extract_lora_weighthelpers to support all four LoRA syntax variants:<lora:filename:weight>,<lora:filename>,<filename:weight>,<filename>
- Mixed variants of the same model (e.g.
<lora:ModelA:1.0>and<ModelA:1.1>) are correctly recognised as duplicates
- Tokenizer now tracks angle-bracket depth (
- Bugfix: Prompt De-Dupe Node - Fixed
prose_thresholdwidget losing its value on workflow load or page refresh- Moved
prose_thresholdfrom optional to required inputs so ComfyUI always enforces the default value - Added
try/exceptguard inprocess()to safely handle any bad values (empty string,None,NaN,< 1), reverting to the default of4 - Added
onConfigureJS hook to sanitize the widget value on workflow restore, preventing empty/NaN values reaching the backend
- Moved
- Bugfix: String Combiner Node - Fixed input connections being dropped on workflow reload and when changing input count
- Removed
onNodeCreatedreconcile call that ran before LiteGraph had restored serialised links, which was the root cause of dropped connections on reload - Reconciliation now runs in
onConfigure(fires after the graph is fully wired) for safe workflow restore - Removed 200ms polling interval; inputs are now only reconciled when the
input_countwidget value actually changes - Reducing
input_countcorrectly removes excess slots and severs their connections as expected
- Removed
- NEW: Prompt De-Dupe Node - Advanced de-duplication engine for prompts
- Removes duplicate tags, phrases, and weighted expressions
- Intelligent weight conflict resolution (explicit vs implicit)
- Grouped bracket de-grouping for complex expressions
- Prose scanning to find and consolidate tags within natural language text
- Zone-based processing with
BREAKandANDdelimiters - Special syntax protection: wildcards, LoRA references, prompt scheduling, nested brackets
- Configurable underscore handling and weight resolution strategy
- Comprehensive console logging of all deduplication operations
- Fully tested with 21+ test cases covering all design specifications
- Added collapse/expand functionality to Dual Prompt node text fields
- Click arrow button on text field border to toggle collapsed state
- Collapsed fields show only the first line, saving vertical space
- "Add Wildcard" buttons hide when text field is collapsed to prevent overlap
- Each field (positive/negative) can be collapsed independently
- Colored borders remain visible at the correct size in both states
- Improved UI layout to properly handle widget spacing in collapsed states
- Entering a prompt name now automatically saves it; the load dropdown updates to show it as the active selection
- Saving under the same name as the currently loaded prompt overwrites silently (intentional update)
- Saving under a different name that matches an existing file shows an overwrite confirmation dialog; cancelling clears the name field
- Loading a prompt updates the name field to match; does not trigger a save
- Save button briefly shows "Saved!" or "Not Saved" as feedback after each save attempt
- Applies to all node types: Dual Prompt, Single Prompt, and Wildcard
- Added
.gitignoreto preserve user-saved prompts and wildcards during updates - User data in
saved/folder is now protected from being deleted on git pull or manual updates
- Bugfix to hide coloured outlines around text fileds when node collapsed
- Initial release
- Dual Prompt Drafter node
- Single Prompt Drafter node
- Wildcard node with multiple output modes
- Prompt Combiner node with up to 25 inputs
- Dynamic wildcard port creation
- Smart comma handling (no double commas)
- Save/Load system
- Example prompts and wildcards
If you encounter any issues or have suggestions, please open an issue on GitHub.
