CXH_JoyTag
Auto-tag any image with Danbooru-style tags
- image
- tags
- count
Feed this node a picture, get back a comma-separated pile of Danbooru-style tags. That's the whole job: 1girl, long hair, outdoors, blue sky, looking at viewer, standing - the exact vocabulary Illustrious, NoobAI, and Pony were trained on. If you're building a LoRA dataset for one of those anime-tag models, or you just want a quick interrogator to reverse-engineer a reference image into a prompt, this is what you reach for.
What it actually is
Under the hood it's fancyfeast's JoyTag model - a vision tagger, not an LLM captioner. That distinction matters: this isn't the same author's JoyCaption (natural-language sentences for Flux-style training), it's the tag-list sibling, closer in spirit to the WD14 tagger. StartHua just wrapped the model in a ComfyUI node. One thing worth knowing about JoyTag specifically: it was built to not go squeamish on NSFW content the way a lot of general vision models do, which is exactly why it works cleanly across hand-drawn anime and photographic images instead of only one or the other.
Community reception has been genuinely good - people who've run it side-by-side with WD14 tend to say JoyTag's vocabulary is deeper and it handles realistic photos better, where WD14 was historically anime-only trained. It's not the newest kid around anymore (JoyCaption gets far more mentions these days for LoRA captioning), but for a pure Danbooru-tag interrogator it still holds up fine.
Inputs and outputs that matter
Four inputs, and you'll only ever touch three of them:
image- the picture to tag. StandardIMAGEinput, wire in anything from a Load Image node.THRESHOLD(default 0.2, range 0.1–1) - the confidence cutoff. Lower it and you get more tags, including shakier guesses; raise it and you get fewer, more confident ones. 0.2 is a reasonable starting point; nudge it up if the output looks noisy, down if it's missing obvious things.addTag- a multiline text box for tags you want force-included regardless of what the model predicts. Handy for a trigger word or a tag you know is true but the model keeps missing.removeTag- the mirror of that: tags you want stripped out even if the model is confident about them. Useful for scrubbing things like watermark or signature tags from a training set before they get baked in.
Two outputs: tags, a single string with everything joined together, and count, the number of tags in it. tags is what you actually use - wire it into a text-save node for dataset captioning, or into a prompt box if you're using this as a reverse-image-to-prompt tool. count is mostly a sanity check, useful if you're batch-processing a folder and want to flag images that came back suspiciously tag-poor (usually means the image was low-res, or the threshold's too high for it).
Installing it
Through ComfyUI Manager: search Comfyui_joytag, install, restart. By hand:
cd ComfyUI/custom_nodes
git clone https://github.com/StartHua/Comfyui_joytag
Then, inside that folder, pip install -r requirements.txt for its dependencies. The one gotcha straight from the README: the author explicitly calls out renaming the cloned folder to Comfyui_joytag if it doesn't land with that exact name - normal for a git clone but worth checking if you grabbed a zip download instead, since GitHub zips add a -main suffix that ComfyUI won't resolve as the right module.
The model weight is a separate download and it's not automatic: grab it from huggingface.co/fancyfeast/joytag and drop it in your checkpoints folder. If the node errors out on first run or the model just isn't loading, this is almost always why - check that the weight actually landed where ComfyUI's checkpoint scanner looks.
Where people get stuck
Past the weight-download step, most friction is generic ComfyUI custom-node stuff: if the node fails to import at all, check the console on startup for the actual Python traceback rather than guessing - a requirements.txt version pin colliding with another installed pack is the usual suspect on a busy install. If tagging quality looks off, it's almost always the threshold: too low buries good tags in noise, too high drops real ones. Start at the default and adjust from there rather than assuming the model's wrong.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| THRESHOLD | FLOAT | 0.200.1–1 | — |
| addTag | STRING | — | |
| removeTag | STRING | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| tags | STRING | — |
| count | INT | — |