MOSS Generate Lite (SatoDive)
One node, draggable boxes, zero sampler spaghetti
- model
- clip
- vae
- image
- mask
- image
- final_prompt
- report
What you're actually looking at
MOSS-Image is OpenMOSS's image model - a 5B DiT with a Qwen3.5-9B text encoder - and ComfyUI core picked it up natively around v0.42. So the boring half is already in your install: UNETLoader, CLIPLoader with a moss_image type, VAELoader. What core doesn't give you is the part that makes the model pleasant to drive.
MOSS Generate Lite is the whole job on one panel: prompt, size, seed, steps, CFG, sampler, negative, plus two things you can't do with stock nodes - a Layout canvas where you drag boxes and give each box its own prompt and its own strictness, and mask-based inpaint that pastes the untouched pixels back exactly.
Fair warning: there's barely any community folklore about MOSS-Image yet - search the subreddits for it and you get nothing. The settings below are the author's, not a crowd's.
How it works under the hood
It's a thin wrapper, and that's the compliment. Sampling goes through ComfyUI's own common_ksampler, so you keep live previews and the real sampler/scheduler lists, and skip-layer guidance uses the built-in SkipLayerGuidanceDiTSimple on layer 22 for the first half of the steps - not a reimplementation.
Layout is the interesting mechanism. Your boxes are compiled at run time into MOSS's official one-line layout prompt: a summary.caption for the whole image plus items, each with a label (object / character / text), a caption, and a bbox in the official abs_centralized / yxyx form - pixels measured from the centre of the frame, y first. Strictness works by appending a sentence to that box's caption: at 0.5 and up, "Only this, nothing else inside this area"; at 0.9, "Exactly as described, with nothing added and nothing else inside this area." Text boxes carry their exact characters too.
At CFG 1 the negative is never encoded at all - a zeroed conditioner goes in its place - so the turbo path is genuinely cheaper, and that's why the negative prompt and SLG do nothing there. With an image connected the latent comes from a VAE encode of it; with a mask too it becomes a noise_mask inpaint with Differential Diffusion, and after decode the result is composited as original * (1 - mask) + new * mask, so everything you didn't paint keeps its exact bytes.
The fields you'll actually touch
Wire model from UNETLoader (optionally through LoraLoaderModelOnly for the speed LoRA), clip from CLIPLoader with type moss_image, vae from VAELoader with the flux2 VAE. Then:
- prompt - what to make. With boxes on the canvas it becomes the global description instead of the whole picture.
- steps / cfg - pair them. 8 / 1.0 with the 8-step DMD LoRA; 4 / 1.0 with a 4-step one; 25–50 / 2.5–3 with no LoRA.
- denoise - only meaningful with an image: 0.5 nudges, 0.85 is new content, 1.0 repaints. Without one it's forced to 1, and the report says so.
- negative / slg - both dead at CFG 1. Above it,
negativedefaults to the official template's list andslgturns on the layer-22 guidance. - mask_grow (default 8) - dilates your painted mask so the repaint bleeds past the brush stroke. Too far and it eats detail.
- layout - JSON. Empty means no layout, and JSON that doesn't parse also means no layout, silently. Quietest way to lose an hour.
Outputs: image, final_prompt (literally the string the encoder read; on a layout run, the compiled JSON), and report (settings, seconds, and reasons - "prompt encode reused", "SLG ignored (needs CFG > 1)"). With save on it writes to output/MOSS with the workflow in the PNG.
Install
ComfyUI v0.42 or newer is a hard requirement: the pack touches comfy/ldm/moss_image and warns in the console when it's missing.
cd ComfyUI/custom_nodes
git clone https://github.com/SatoDive/ComfyUI-MOSS-Image-Studio-Lite-SatoDive
# restart ComfyUI
No pip dependencies at all - unusual and welcome. The weight is in the models, from Comfy-Org/MOSS-Image on Hugging Face: moss_image_sft_int8_convrot (or bf16) in diffusion_models, qwen3.5_9b_int8_convrot in text_encoders, flux2-vae in vae - that's Flux 2's VAE, so you may already have it. The optional 8-step turbo LoRA is MOSS-Image-SFT-8-steps-dmd by lodestones, at 1.0.
Where people get burned
The node not appearing in the menu is almost always an old ComfyUI - the console line says so. Then the loaders: the CLIP type dropdown has to be moss_image, and the VAE has to be the flux2 one. Another family's VAE decodes this model to mush and nothing warns you.
Connected an image but your width/height did nothing? The image wins, by design, and the report says "size from the image". And a 5B DiT next to a 9B encoder is not small - the bf16 pair beside your browser on an 8GB card is how you meet the swap file.
Inputs (20)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | UNETLoader (moss_image_*) -> optional LoraLoaderModelOnly (speed LoRA). | |
| clip | CLIP | CLIPLoader, type moss_image. | |
| vae | VAE | VAELoader, flux2 vae. | |
| prompt | STRING | What to make. With layout boxes it becomes the global description. | |
| width | INT | 1024256–4096 | — |
| height | INT | 1024256–4096 | — |
| seed | INT | 00–18446744073709550000 | — |
| steps | INT | 81–200 | 8 with the 8-step DMD LoRA, 4 with the 4-step LoRA, 25-50 without a LoRA. |
| cfg | FLOAT | 1.01–10 | 1 with a speed LoRA (fastest: the negative is not even encoded), 2.5-3 without. |
| sampler_name | COMBO | euler | 44 options: euler, euler_cfg_pp, euler_ancestral, euler_ancestral_cfg_pp, heun, heunpp2, +38 |
| scheduler | COMBO | simple | 9 options: simple, sgm_uniform, karras, exponential, ddim_uniform, beta, +3 |
| denoise | FLOAT | 1.000–1 | With an image: 0.5 = small change, 0.85 = new content, 1 = repaint. |
| negative | STRING | nsfw, worst quality, bad anatomy, watermark, jpeg artifact | Only used when CFG > 1. |
| slg | BOOLEAN | false | Official skip-layer guidance on the negative branch (layer 22, first half of the steps). Only works with CFG > 1. |
| mask_grow | INT | 80–128 | Inpaint: grow the painted mask by this many pixels (soft edges). |
| save | BOOLEAN | true | — |
| filename_prefix | STRING | MOSS/studio | — |
| layout | STRING | Layout boxes as JSON (drawn on the node's canvas). Empty = no layout. | |
| imageopt | IMAGE | img2img / inpaint source (its size wins). | |
| maskopt | MASK | Inpaint area (paint it in Load Image's mask editor). |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| final_prompt | STRING | Exactly what the model read. |
| report | STRING | — |