QWEN IMAGE 2.1 ONE STUDIO (TJ)
Eight modes, one node, no mask file
- pipe
- image
- prompt
- settings
One node instead of four workflows
The Qwen-Image-Edit line is where image work stopped needing a mask or a control map: hand it a picture and a sentence and the change happens. The catch is structural - the model re-emits the whole frame, so pixels nobody asked about move, and the standard 2026 fix is to bolt a mask back on around it.
QWEN IMAGE 2.1 ONE STUDIO (TJ) wraps the Qwen Image 2.1 family in one ComfyUI node and gives you T2I, I2I, Ref to Image (up to 10 references), Edit (Image 1 plus up to 9 more), Inpaint, Outpaint, Upscale and POSE as mode pills inside a single panel. No wiring, no separate workflow files, no uploading a mask PNG. Faceswap and camera Angle are deliberately left out - the sibling Qwen Image Edit 2511 ONE STUDIO (TJ) node in the same pack has both.
How it actually works
The Python class is almost empty on purpose: no required inputs, and its one method just reads the last image this node saved back off disk. The real work happens when you press ▶ Generate (not ComfyUI's top RUN) - the front-end assembles a graph in JavaScript and posts it to the API:
UNETLoader (or UnetLoaderGGUF for a .gguf) → CLIPLoader of type qwen_image → VAELoader, an optional QwenImage21Cache wrapper (on by default), then TextEncodeQwenImage21 - which takes prompt, negative prompt, output resolution and up to ten images (images.image_1 … image_10) and hands back positive, negative and its own conditioning latent - then KSampler → VAEDecode → SaveImage into output/one_qwen21/.
That's 2.1's own encoder, paired with a Qwen3-VL-family text encoder rather than 2511's Qwen2.5-VL + FluxKontext chain - if what you have on disk is 2511 weights, use the 2511 node in this pack.
The inputs and output that matter
Exactly two inputs, both optional:
- prompt_override (STRING) - external prompt text, appended before the node's internal prompt.
- pipe (
TJ_PROMPT_PIPE) - takes a record fromPromptDBLoader(TJ)in the author's other pack. At generation time the fields it carries (prompt, seed, steps, cfg, sampler, scheduler) override this node's settings, missing ones keep their own values, and the UI never changes. The model does not come over the pipe.
The only output is image (IMAGE, single) - the most recent image the node generated, which is what the top RUN emits. Wire it into a Preview/Save node or feed it downstream; no batch, no latent.
The modes, and the one with a real idea in it
Inpaint and Edit are mask-free: you draw on the image inside the node (pen/line/circle/rect, Shift for a perfect shape, [ ] brush size, \ undo, right-click eraser, Enter to commit). The annotated frame replaces <imageN> at its own slot instead of being appended as an extra reference - the sensible reading of an edit prompt, and the fix for a bug where annotating Image 1 shifted every later <imageN> by one. Outpaint pads the canvas with ImagePadKJ and prepends a system prompt telling the model to continue the composition into the pad colour.
POSE is the interesting one: two queued passes. The cropped pose image goes through SAM3D-Body (SAM3DBody_Loader → _Predict → _Smooth → _Render, core ComfyUI nodes) to make a 3D pose render; that render becomes <image1>, your character <image2>, and the VNCCS PoseStudio LoRA copies the pose over. Crop first (✂ Crop Pose Image) - both files are picked in ⚙ Settings, not on the node.
Install
Manager → Install Custom Nodes → search ComfyUI-TJ_NODE_STUDIO_ONE. Manually:
cd ComfyUI/custom_nodes
git clone https://github.com/designloves2/ComfyUI-TJ_NODE_STUDIO_ONE.git
Then the step everyone skips: run install_requirements.sh (Windows: install_requirements.bat) once and restart. Manager installs Python packages but never dependency node packs - Outpaint needs ComfyUI-KJNodes (ImagePadKJ), Upscale needs ComfyUI-SeedVR2, .gguf loading needs ComfyUI-GGUF, and missing packs show as a startup banner.
Models are all by hand - the pack ships none. UNET → models/diffusion_models/, Qwen3-VL text encoder → models/text_encoders/, VAE → models/vae/. POSE wants VNCCS_QI2_PoseStudioV1.1.safetensors in models/loras/ and sam_3d_body_dinov3_bf16.safetensors in models/detection/; Upscale wants SeedVR2's DiT + VAE in models/SEEDVR2/.
Where people get burned
"Unknown node class" or a missing-required-input error when you hit Generate almost always means your ComfyUI build predates TextEncodeQwenImage21 / QwenImage21Cache. The pack's own graph builder carries a note that it never verified that signature against a live install, so update ComfyUI before blaming the node.
An empty model dropdown isn't a broken install - hit ↻ Refresh Models in ⚙ Settings.
POSE fails with Select the VNCCS PoseStudio LoRA in ⚙ Settings until you pick that LoRA, and differently if you skipped the crop. It loads its own LoRA and no ModelSamplingFlux, so a general LoRA stack doesn't apply.
Ten 4K references are slow and VRAM-hungry for no quality gain - the encoder's resolution field only sets your output size, not how big the references it reads are. Settings has a "Reference Image Max Megapixels" cap for exactly this; at 0 it sends them as uploaded.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| prompt_overrideopt | STRING | External prompt override — replaces the node's own prompt. Takes the text of a PromptDBLoader (TJ) or any text node wired in. | |
| pipeopt | TJ_PROMPT_PIPE | PromptDB pipe (TJ_NODE). At generation, fields present in the pipe override this node's settings; missing fields keep the node's own values. The node's UI is never changed. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| prompt | STRING | — |
| settings | STRING | — |