XImageCompare
A/B your images and masks right on the canvas, not in a gallery
- image_a
- image_b
- A
- B
Picking between two generations is half of what ComfyUI is for, and doing it well needs a proper A/B viewer - not two preview nodes you squint between. XImageCompare is an interactive comparator with four modes - slide, spotlight, blend, and an auto ping-pong that flips between A and B on a timer - and it accepts either IMAGE or MASK inputs. It's the kind of node that doesn't add generation capability and feels like a toy until you're comparing a sharpened version against the original and realize how much faster a draggable divider is than your eyeballs.
How it works
image_a and image_b are MatchType ports, so each accepts an image or a mask and they don't have to be the same flavor - compare an image against a mask if that's your thing. The node renders the comparison in a dedicated viewer and hands both inputs straight through as outputs A and B, so it slots into a graph without disturbing the data path. It's effectively a display node with a passthrough, which is the polite way to add inspection without breaking the chain.
The viewer state lives in two hidden widgets: __compare_mode (0 = the mode selector) and __compare_slider (50 = the divider position). You don't set those by hand; they're the frontend's working memory, driven by the pack's ximagecompare_extension.js. There's also swap_ab, which flips both the display and the output order of A and B - handy when a pipeline naturally produces things in the wrong order and you don't want to rewire.
Settings that matter
- save_to_output (default false) - when off, images go to ComfyUI's temp cache and are cleaned on restart; turn it on to persist them in
output/XImageCompare. The changelog's framing is the useful part: with the temp cache you get a fresh viewer every session; with output saving you keep files. - swap_ab - swaps display and output order.
- image_a / image_b - the optional inputs; a missing one just shows the other.
Outputs are A and B, matching the input types.
Installing it
Part of ComfyUI-Xz3r0-Nodes - one install covers it. ComfyUI Manager: search ComfyUI-Xz3r0-Nodes. Or:
cd ComfyUI/custom_nodes
git clone https://github.com/Xz3r0-M/ComfyUI-Xz3r0-Nodes.git
cd ComfyUI-Xz3r0-Nodes
pip install -r requirements.txt
Restart ComfyUI. No FFmpeg needed here - this is a pure frontend/display node, so you can ignore the pack's audio dependency warning for this one.
Gotchas
Because the comparison is a frontend feature, it depends on the pack's web extension loading; if you run a stripped frontend or the extension is blocked, you get the passthrough but no interactive viewer. Also, temp-cache mode is explicitly non-persistent - "survives page refresh" is the selling point of save_to_output, and the default isn't that. And remember it's a display node: outputs are pass-through, so don't expect it to do any image processing. If you're comparing upscaled versions, the KB's reminder applies - a comparator tells you which looks better, it doesn't tell you whether the difference is worth the VRAM.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| save_to_output | BOOLEAN | false | Enable: save to output folder (persistent, survives page refresh). Disabled: use temp cache (cleaned on restart) |
| swap_ab | BOOLEAN | false | Swap both the display and output order of Image/Mask A and B |
| __compare_mode | INT | 0 | — |
| __compare_slider | FLOAT | 50.00 | — |
| image_aopt | COMFY_MATCHTYPE_V3 | Image or Mask A for comparison (optional) | |
| image_bopt | COMFY_MATCHTYPE_V3 | Image or Mask B for comparison (optional) |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| A | COMFY_MATCHTYPE_V3 | Passthrough of A |
| B | COMFY_MATCHTYPE_V3 | Passthrough of B |