Aioli Nodes — ComfyUI Custom Node Suite
Two utility nodes for outpainting and inpainting in ComfyUI.
Installation
Via ComfyUI Registry (recommended)
Search "Aioli Nodes" directly in the ComfyUI Manager → Install Nodes.
Via Git URL
https://github.com/aiolicollective/aioli-nodes
Manual installation
- Copy the
aioli-nodesfolder intoComfyUI/custom_nodes/ - Restart ComfyUI
- The nodes appear under the Aioli Nodes category
No extra dependencies — only math (Python stdlib), torch and Pillow (already bundled with ComfyUI).
🖼️ Ratio Outpaint Calc
Prepares an image for outpainting to a standard aspect ratio.
Automatically computes padding and generates the mask.
Inputs
| Parameter | Type | Description |
|---|---|---|
| image | IMAGE | Source image |
| ratio | dropdown | none · 1:1 · 4:5 · 5:4 · 3:4 · 4:3 · 16:9 · 9:16 |
Outputs
| Output | Type | Description |
|---|---|---|
| image_padded | IMAGE | Image padded with neutral grey (0.5) |
| mask | MASK | Binary mask (0 = keep, 1 = generate) |
Workflow
Load Image → 🖼️ Ratio Outpaint Calc → VAE Encode (Inpaint) → KSampler
📐 BBox Multiple Fix
Plugs in right after Mask Bounding Box (ComfyUI Essentials).
Rounds the crop to the chosen multiple and optionally upscales to a Flux-friendly resolution.
The node ensures the inpainted region stitches back pixel-perfectly onto the base image — no border artefacts, no alignment drift.
Example
The inpaint applied back onto the base image fits the original contours exactly — pixel-perfect edges, no alignment drift.
Inputs
| Parameter | Type | Description |
|---|---|---|
| image | IMAGE | Full source image (before crop) |
| mask | MASK | Full source mask (before crop) |
| x | INT | x output from Mask Bounding Box |
| y | INT | y output from Mask Bounding Box |
| width | INT | width output from Mask Bounding Box |
| height | INT | height output from Mask Bounding Box |
| multiple | dropdown | 8 (VAE) · 32 (SD1.5) · 64 (SDXL/Flux) |
| target | dropdown | none · 512 · 768 · 1024 · 1536 · 2048 |
Outputs
| Output | Type | Description |
|---|---|---|
| image_cropped | IMAGE | Cropped image (scaled if target is set or if bbox > 2048px) |
| mask_cropped | MASK | Cropped mask (scaled if target is set or if bbox > 2048px) |
| x | INT | x position for ImageCompositeMasked |
| y | INT | y position for ImageCompositeMasked |
| orig_width | INT | Crop width BEFORE scale (use for resize-back after VAE Decode) |
| orig_height | INT | Crop height BEFORE scale (use for resize-back after VAE Decode) |
| width | INT | Final width (after scale) |
| height | INT | Final height (after scale) |
Scaling behaviour
| Situation | Behaviour |
|---|---|
bbox ≤ 2048, target none |
Round up to multiple only — no scale |
| bbox ≤ 2048, target set | Upscale crop to target — pixel-perfect ratio via GCD |
| bbox > 2048 (any target) | Downscale crop to fit 2048px — ratio preserved via GCD |
Workflow without scale
BBox Fix → VAE Encode → KSampler → VAE Decode → ImageCompositeMasked ← x, y
Workflow with upscale / downscale
BBox Fix → VAE Encode → KSampler → VAE Decode
↓ orig_width, orig_height ↓
↓ x, y → ImageResize+ ←────────┘
↓
ImageCompositeMasked ← x, y
🔁 Example Workflow — Flux2Klein Inpaint
A complete, ready-to-use inpaint workflow for Flux2Klein (9B), packaged as a ComfyUI subgraph (FLUX2KLEIN_INPAINT).
Required models
| Role | File |
|---|---|
| UNet | flux2/flux-2-klein-9b-fp8.safetensors |
| VAE | flux2/flux2-vae.safetensors |
| Text encoder | qwen_3_8b_fp8mixed.safetensors |
Required custom nodes
- Aioli Nodes (this repo) —
BBoxMultipleFix - ComfyUI Essentials —
MaskBoundingBox+,ImageResize+ - ComfyUI KJNodes —
GrowMaskWithBlur - rgthree-comfy —
Image Comparer(optional, for before/after preview)
Subgraph inputs
| Input | Description |
|---|---|
| IMAGE | Source image (with painted mask) |
| MASK | Inpaint mask |
| Resize_Megapixels | Working resolution in megapixels (default: 4) |
| PROMPT | Inpaint prompt |
| Resize_Inpaint_Target | BBox target size (none · 512 · 768 · 1024 · 1536 · 2048) |
Internal pipeline
LoadImageOutput (with mask painter)
└→ FLUX2KLEIN_INPAINT subgraph
├── ImageScaleToTotalPixels (resize source to working MP)
├── MaskBoundingBox+ (detect mask region)
├── BBoxMultipleFix (crop + scale for Flux, cap 2048px)
├── GrowMaskWithBlur (soften mask edges)
├── VAEEncode × 2 + SetLatentNoiseMask
├── CLIPTextEncode → ReferenceLatent → FluxGuidance
├── Flux2Scheduler + KSamplerSelect + RandomNoise
├── SamplerCustomAdvanced
├── VAEDecode
├── ImageResize+ (resize back to orig_width × orig_height)
└── ImageCompositeMasked (stitch result onto source)
└→ SaveImage + Image Comparer (before / after)
Usage
- Download the JSON and drag it into ComfyUI
- Point
LoadImageOutputto your image and paint your mask - Set your prompt and target resolution in the subgraph inputs
- Run — the result is composited pixel-perfectly back onto the source image
