ComfyUICharacterComposer
ComfyUICharacterComposer turns Qwen character work into dropdowns
- image1
- image2
- image3
- positive_prompt
- negative_prompt
- image1
- image2
- image3
ComfyUICharacterComposer isn't a generator and it doesn't call any API. It's a prompt-composition layer that sits in front of Qwen-Image-Edit and turns "rewrite the whole sentence and hope" into a set of dropdowns. You pick a hair color, an outfit, a vibe, and it assembles the final positive and negative prompt strings for you - deterministically, from a seed, with a JSON tag library doing the heavy lifting.
Why bother? Qwen-Image-Edit is where consistent character work actually happens these days - you generate once, then edit that image into new poses and scenes (the whole IP-Adapter stack mostly stopped being the answer). The catch is that its prompt is where people fight it. This node exists for iteration: flip hair_color from blonde to brunette, hit run with the same seed, and everything else stays put. The author pitches it as a workflow layer on top of the Qwen pipeline rather than a replacement, and honestly that's the right framing. The one skeptical comment on their release thread said Qwen AIO is already solid on its own - fair. This buys you speed and reproducibility, not magic.
How it works
Under the hood it's a pure-Python engine with zero dependencies (no requirements.txt, no torch calls). Every run does roughly this:
- Reads a JSON tag library -
tags.jsonby default, withtags_NSFW.jsonas the selectable spicier alternative. Thetag_filedropdown lists whatever JSON files it finds. - Scans your
input_promptfor known trait keywords (using the alias map, soblondstill matchesblonde). - Merges that with your UI dropdowns. Every trait input is
auto/random/none/ a specific value, andrandompicks are driven by arandom.Random(seed)- which is why the same seed reproduces the same character. - Applies composition bias and cleanup:
composition_modeandsmart_presetbias defaults,_composer_rulesin the JSON handle conflicts (akokoshnikheaddress drops theushankafur hat), and a complexity guard trims low-priority traits when the prompt gets overcrowded. - Replaces wildcards -
{hair_color}in your base prompt gets substituted with the final choice.
The node is OUTPUT_NODE-style: it prints the assembled prompt to the read-only final_prompt_preview field so you can see what it actually sent, which is the best debug tool this thing has.
The inputs that matter
You don't touch most of the ~40 inputs. Start with these:
input_prompt- your natural-language base, with{tags}for explicit wildcard injection.seed- the reproducibility switch. Same seed, same picks.smart_preset/composition_mode- high-level bias.safe portrait,winter fashion,paired cinematic, etc. Leave everything else onautountil you need an exact override.extra_modifiers- style flavoring; the default is heavily "gravure / tropical glamour", so expect to edit this if that's not your niche.
Outputs are exactly five: positive_prompt and negative_prompt strings, plus image1 / image2 / image3 passthroughs. Wire the strings into your Qwen-Image-Edit conditioning, and the images into the multi-reference encoder (v2.0 accepts up to three reference images for image-to-image). Leave them disconnected and it works as text-to-image. The bypass_generator toggle returns your raw input_prompt untouched - handy for isolating whether the node or the model is the problem.
Install
Through ComfyUI Manager (search "comfyui-character-composer"), or:
cd ComfyUI/custom_nodes
git clone https://github.com/unh1nge/comfyui-character-composer
Then restart ComfyUI - it appears under Prompt. No pip packages, no model files inside the pack. The catch is the recommended stack: the author targets Qwen-Image-Edit-Rapid-AIO (Phr00t's all-in-one checkpoint) and ships a ready-made QWEN AIO CC 3X WORKFLOW.json. That checkpoint is the real download, and it's a 20B-class model - in practice people run community GGUF quantizations, not bf16, unless you've got the VRAM.
Common gotchas
- The built-in negative prompt is niche-specific. It ships with terms like "no twins, no deformities, no futanari" baked in - written for the author's "cute & tropical gravure" corner. If you're generating something else, don't blindly trust
negative_prompt; trim it. - Random output with no seed discipline.
autotraits withfill_auto_traitsoff leave gaps in your prompt. If a character comes back missing hair, that's usually an unfulfilledautotrait, not the model. - Qwen drift is not this node's bug. Faces sliding across an edit chain is a Qwen-Image-Edit structural limitation (it re-emits the whole frame). This node can't fix identity drift; it just makes the prompt part reproducible.
It's a niche, opinionated tool - one author's answer to a specific workflow. If you live in Qwen character generation, it's genuinely the fastest way to iterate. If you're on SDXL, it's not for you yet.
Inputs (54)
| Name | Type | Default | Description |
|---|---|---|---|
| input_prompt | STRING | — | |
| final_prompt_preview | STRING | Run the node to preview the final prompt here. | Read-only preview of the final prompt from the last run. |
| seed | INT | 00–18446744073709550000 | — |
| extra_modifiers | STRING | gravure, photorealistic, soft lighting, high detail, 8k, ultra realistic, cinematic composition, sensual mood, soft focus, warm glow, intimate atmosphere, cute aesthetic, glossy aesthetic, tropical glamour, mythic elegance, moody shadows | — |
| generation_profile | COMBO | custom | High-level bundled preset for the most common good generation setups. |
| smart_preset | COMBO | none | Workflow-level preset that biases composition and stability defaults. |
| composition_mode | COMBO | auto | High-level composition intent used to bias defaults and conflict handling. |
| subject_count | COMBO | auto | 7 options: auto, random, 1, 2, 3, 4, +1 |
| detail_level | COMBO | balanced | Controls how many secondary details are added to the final prompt. |
| style_strength | COMBO | balanced | Controls how strongly vibe, style, and scene flavoring are applied. |
| fill_auto_traits | BOOLEAN | false | — |
| reset_overrides | BOOLEAN | false | Force all trait override controls back to auto mode for this generation. |
| randomize_look_keep_position | BOOLEAN | false | Randomize look traits (subject/body/hair/eyes/outfit/etc.) while keeping pose and composition controls unchanged. |
| bypass_generator | BOOLEAN | false | — |
| preserve_input_position | BOOLEAN | false | If True and a reference image is supplied, add hints to preserve subject positions and composition from the input image. |
| preserve_character_look | BOOLEAN | false | Strict: prevent changing known look-related tags (hair_color, hair_style, eye_color, outfit, makeup, body_type, chest_size, fantasy_race, ethnicity) from UI selections or prompt inference. |
| outfit_mode | COMBO | auto | 3 options: auto, random, keep |
| tag_file | COMBO | tags.json | Select which tags JSON file to use for generation. |
| --- CORE CREATIVE --- | STRING | — | |
| preset | COMBO | auto | 30 options: auto, random, none, tags.json::boudoir intimate aesthetic, tags.json::cinematic film look, tags.json::dreamlike soft haze, +24 |
| subject | COMBO | auto | 61 options: auto, random, none, tags.json::adventurer, tags.json::artist, tags.json::assassin, +55 |
| gender | COMBO | auto | 5 options: auto, random, none, female, male |
| outfit | COMBO | auto | 70 options: auto, random, none, tags.json::azure blue santa outfit with white fur and ushanka hat, tags.json::bikini minimal fabric, tags.json::blue fur-trimmed coat with tall boots, +64 |
| pose | COMBO | auto | 38 options: auto, random, none, tags.json::against wall pose relaxed lean, tags.json::arms up stretch elongated body, tags.json::bending slightly forward dynamic angle, +32 |
| interaction | COMBO | auto | 43 options: auto, random, none, tags.json::attending concert , tags.json::attending event , tags.json::biking , +37 |
| setting | COMBO | auto | 54 options: auto, random, none, tags.json::beach club cabana with sunlit curtains, tags.json::cozy bedroom with soft lamplight, tags.json::cruise ship poolside with bright deck lights, +48 |
| --- CHARACTER LOOK --- | STRING | — | |
| body_type | COMBO | auto | 31 options: auto, random, tags.json::athletic, tags.json::average build, tags.json::busty, tags.json::curvy, +25 |
| chest_size | COMBO | auto | 23 options: auto, random, none, tags.json::busty, tags.json::full, tags.json::large, +17 |
| age | COMBO | auto | 20 options: auto, random, none, tags.json::30s, tags.json::40s, tags.json::adult, +14 |
| ethnicity | COMBO | auto | 52 options: auto, random, tags.json::african, tags.json::afro-latina, tags.json::arabian, tags.json::brazilian, +46 |
| fantasy_race | COMBO | auto | 50 options: auto, random, none, tags.json::angel with white wings, tags.json::bunny girl with long ears, tags.json::catgirl with cat ears and tail, +44 |
| hair_color | COMBO | auto | 73 options: auto, random, none, tags.json::ash blonde muted tone, tags.json::black, tags.json::blonde, +67 |
| hair_style | COMBO | auto | 48 options: auto, random, none, tags.json::beach waves, tags.json::bedhead tousled, tags.json::braided, +42 |
| eye_color | COMBO | auto | 27 options: auto, random, none, tags.json::amber eyes warm glow, tags.json::blue eyes clear tone, tags.json::brown eyes deep, +21 |
| expression | COMBO | auto | 46 options: auto, random, none, tags.json::alluring captivating look, tags.json::biting lip suggestive, tags.json::confident relaxed expression, +40 |
| makeup | COMBO | auto | 35 options: auto, random, none, tags.json::bold makeup high contrast, tags.json::dewy skin hydrated glow, tags.json::faux freckles natural detail, +29 |
| --- CAMERA & FRAMING --- | STRING | — | |
| focus | COMBO | auto | 30 options: auto, random, none, tags.json::cleavage focus composition, tags.json::close-up tight crop, tags.json::face focus sharp detail, +24 |
| camera_angle | COMBO | auto | 29 options: auto, random, none, tags.json::POV angle immersive perspective, tags.json::close-up portrait tight framing, tags.json::cowboy shot mid-thigh framing, +23 |
| camera_gear | COMBO | auto | 18 options: auto, random, none, tags.json::85mm lens portrait compression, tags.json::Canon R5 sharp detail, tags.json::Kodak Portra 400 color profile, +12 |
| --- STYLE & SCENE --- | STRING | — | |
| vibe | COMBO | auto | 39 options: auto, random, none, tags.json::90s aesthetic, tags.json::boudoir mood, tags.json::editorial fashion, +33 |
| style_adjective | COMBO | auto | 33 options: auto, random, none, tags.json::alluring presence, tags.json::bold contrast, tags.json::cute appeal, +27 |
| creative_twist | COMBO | auto | 31 options: auto, random, none, tags.json::dreamlike haze, tags.json::editorial polish, tags.json::ethereal glow, +25 |
| background_mood | COMBO | auto | 39 options: auto, random, none, tags.json::bright morning light crisp, tags.json::candlelit velvet shadows, tags.json::candlelit warm flicker, +33 |
| atmosphere | COMBO | auto | 42 options: auto, random, none, tags.json::crisp winter air, tags.json::electric night air, tags.json::enchanted moonlit mist, +36 |
| --- OPTIONAL EXTRAS --- | STRING | — | |
| accessory | COMBO | auto | 59 options: auto, random, none, tags.json::anklet small detail, tags.json::belt structured detail, tags.json::body chain metallic highlight, +53 |
| prop | COMBO | none | 31 options: auto, random, none, tags.json::banana, tags.json::book casual detail, tags.json::camera meta element, +25 |
| background_prop | COMBO | none | 28 options: auto, random, none, tags.json::bed with silk sheets, tags.json::candle clusters on side tables, tags.json::flowers natural, +22 |
| image1opt | IMAGE | — | |
| image2opt | IMAGE | — | |
| image3opt | IMAGE | — |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| positive_prompt | STRING | — |
| negative_prompt | STRING | — |
| image1 | IMAGE | — |
| image2 | IMAGE | — |
| image3 | IMAGE | — |