Videos Concatenate (Horizontal)
Side-by-Side Stitching Without Leaving ComfyUI
- images_left
- images_right
- images
The two-video A/B you keep doing by hand
You've got two clips and you want them in one frame. Sampler comparison, original-vs-upscaled, prompt A/B - whatever it is, you need to actually see them at the same time, and ComfyUI has no built-in way to do that for image sequences. This node is the fix. It's called Videos Concatenate (Horizontal), but don't read too much into the name: it operates on any IMAGE batch, which is exactly what a video is once you're inside a graph.
How it works
In ComfyUI, a video isn't a file - it's a stack of frames living in the batch dimension of a tensor shaped [batch, height, width, channels]. The node takes two of those stacks (left and right inputs), pairs them up frame by frame, and glues each pair together along the width axis. What comes out is a single batch where every frame is twice as wide, in the same frame order it went in. Mechanically that's a per-frame torch.cat with a progress bar from comfy.utils, and it prints the input dimensions to your console as it goes. The "Videos" in the name is more honest than most - it just happens to work on any image batch, video or not.
The inputs that matter
There are only two, both IMAGE, both required, and both named exactly like they behave:
- images_left - the batch that ends up on the left half
- images_right - the batch that ends up on the right half
There are no parameters to fiddle with. No gap toggle, no padding, no alignment option. The output width is simply left width plus right width. Wire the single images output into anything that consumes IMAGE - VHS_VideoCombine to render an mp4, SaveAnimatedWEBP, or a PreviewImage node if you just want to eyeball one frame.
The one thing the node is strict about: both batches must have the same number of frames, the same height, and the same channels. Width is the only dimension that can differ - stitch a 640-wide clip next to a 512-wide clip and it'll happily do it. If frames, height, or channels mismatch, it raises a ValueError that names the exact constraint you broke. For two clips of different lengths, trim or pad one first; VideoHelperSuite can do either.
Install
This is a genuinely small pack. stevenwg/ComfyUI-VideoGrid is a cookiecutter-scaffolded utility with exactly two nodes, no Python dependencies, and no model downloads - the pyproject.toml dependency list is literally empty, which is rare enough to be worth celebrating. Install from ComfyUI Manager by searching ComfyUI-VideoGrid, or do it by hand:
cd ComfyUI/custom_nodes
git clone https://github.com/stevenwg/ComfyUI-VideoGrid
Then restart ComfyUI. It's GPL v3 and sitting at version 0.0.3, so set expectations accordingly: a focused little tool, not a framework.
Where people get burned
The classic mistake is forgetting the inputs must already share a height. Comparing an SDXL 1024×1024 run against a 512×512 run? Resize first - the node won't do it for you. Also remember there's no seam between the two halves; if you want a visible divider, build padding upstream. And when it throws "Both video sequences must have the same number of frames, height, and channels for horizontal stacking," read your console - it prints both inputs' dimensions right before failing, so the mismatch is usually visible at a glance.
It's not flashy, and a scripting pack could replicate it. But for a quick side-by-side this is two wires and you're done. That's the whole pitch.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| images_left | IMAGE | Left image batch | |
| images_right | IMAGE | Right image batch |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| images | IMAGE | — |