A LoRA toolkit for ComfyUI: pick which LoRA subfolders a node draws from so you're only ever searching the models you're working with, stack up to 12 LoRAs across several models from one node, and run a proper XY LoRA test bench in a single queue.

The Fantastic Lora Loader with 12 lora slots and presets

Filter which subdirectories are used when searching for loras

Search for a Lora from only your selected folders. Save your favorites for quick access

Adjust loras strength for each connected model

Pick your Loras and the strengths to try, add a control image, and queue once — every combination generates on its own

Effortlessly generate multiple iterations to compare Loras and their strengths. Rearrange the output as you see fit

Choose between modern and classic grid outputs
One loader instead of a chain of them. Twelve LoRA slots in a single node, feeding up to five separate MODEL outputs. Each LoRA can go to all five models, or just one, or to different models at different strengths — so a two-pass workflow where the refiner needs your detail LoRA at 0.4 and the base pass wants it at 1.0 is one node, not two loaders and a mental note. Slot order is apply order and you drag slots to change it. A footer prints exactly what each model output will receive, in order, so you can confirm the wiring matches your intent without tracing wires.
Alongside that: named presets that save and reload your whole stack (or merge into it without wiping what's there), folder filtering for people whose loras directory holds dozens of model subfolders, and randomizer slots that roll a different LoRA each queue — useful for rediscovering things buried in a large collection.
An XY LoRA test bench that runs in one queue. The Plotter takes the same slot grid, but instead of stacking your LoRAs it tests them against each other — LoRAs on one axis, strengths on the other, exactly the XY plot you'd build by hand. It emits one MODEL per test cell as a list output, so ComfyUI runs your sampler once per cell automatically — you hit Queue once and get the whole comparison, no batch loops or manual re-queueing. Feed the results to the Image Saver for a single labelled grid image — choose between a modern text-overlay layout or a classic A1111-style grid with labels down the margins — or to the Grid Viewer to browse them interactively on the canvas. It can also hold a set of LoRAs constant across every cell, and include a no-LoRA baseline so you can see what each one is actually contributing.
Mirror LoRA selections that live somewhere else. The Mimic exists for when the LoRA list is authored in a node that isn't this one — rgthree's Power Lora Loader, the stock loader, Efficiency or Comfyroll stackers — and you want that same list applied to a different model path. It reads the source's configured LoRAs and applies them to its own MODEL and CLIP, so you're not taking a wire from a model that's already been modified. Each mirrored LoRA can track the source live or be unlinked for an independent strength.
Two cases it's specifically built for: split high/low models like Wan 2.2, where LoRAs come as ..._high / ..._low pairs and it can find and substitute the matching half automatically; and subgraphs, where a companion node bridges the boundary so a Mimic outside can see loaders buried inside (or vice versa). It's the experimental corner of the pack — it reads other nodes' settings by inspecting the graph rather than through any official interface, so verify it mirrored what you expected before trusting a long run.
ComfyUI-Manager (easiest): open the Manager → Install Custom Nodes → search Fantastic Loras → Install → restart when prompted.
Manual:
cd ComfyUI/custom_nodes
git clone https://github.com/Adudeguyman/comfyui_fantastic-lorasRestart ComfyUI, then hard-refresh your browser (Ctrl+Shift+R). Nothing else to install.
Two ready-made workflows are in the example_workflows folder — drag either onto the ComfyUI canvas to try things out.
Nodes 2.0 ready. Everything works under both the classic canvas and the newer Nodes 2.0 renderer, and you can switch between them at any time without breaking a saved workflow. The node panels are real interface elements rather than canvas drawings, so they behave the same either way.
- Add Fantastic Lora Loader 📁 (double-click the canvas, search "fantastic").
- Wire your MODEL into it and its output onward to your sampler. Wire CLIP too if your setup uses text-encoder LoRA weights — for models where LoRAs only touch the diffusion model, you can leave it unconnected.
- Click Add lora… and pick one. It lands in the first empty slot.
- Adjust its strength with − + or by scrolling over the number.
- Queue as normal.
That's the whole basic loop. Everything below is optional.
| Node | What it's for |
|---|---|
| Fantastic Lora Loader 📁 | The main one. Stack LoRAs onto one or several models. |
| Fantastic Lora Plotter 📊 | XY test bench — sweep LoRAs against strengths and get a comparison grid. |
| Fantastic Plotter Global Lora 🌐 | LoRAs applied to every image in a comparison. |
| Fantastic Plotter Image Saver 📊 | Turns the comparison into one labelled grid image. |
| Fantastic Plotter Grid Viewer 🔍 | Browse the results interactively, zoom, and pick winners. |
| Fantastic Lora Mimic 🪞 | Mirror a LoRA list authored in another loader onto an independent model path. |
| Fantastic Any Selector 🎯 | A filename picker with folder filtering, for any loader. |
| Fantastic Seeds 🌱 | A seed source with fixed / randomize / locked modes and a history. |
All of them appear under loaders in the add-node menu.
The loader is one self-contained panel inside the node.
- Add lora… — opens the picker. Type to search; ☆ stars a LoRA so it floats to the top next time.
- 🎲 Add random — adds a slot that picks a random LoRA for you (see Randomizer).
- n / 12 — how many of the 12 slots are filled.
- chains N/5 − + — how many models this node feeds (see Multiple models).
- .ext — show or hide the
.safetensorson the end of every name. - Theme — four colour schemes: Fantastic Teal, Boring Blue, Like, TEAL Teal, and Accountant. Changing it restyles the panel and the node colour across every node in the pack. If you've hand-picked a colour for a node yourself, the theme leaves it alone.
Twelve slots in two columns. Click any empty one to add a LoRA. Each filled slot shows:
- ● green dot — click to disable this LoRA without removing it.
- number — the order it's applied in. Reading order: left to right, then down.
- folder path above the LoRA name — click the name to swap it for a different one.
- M1 M2 … — which models this LoRA is feeding, when you're using more than one.
- − 1.00 + — the strength. Click the steppers, scroll over it, or type a number. This is the base strength every model uses unless you override one individually under ⚙.
- ⚙ — per-model routing and per-model strengths, plus randomizer settings. This is where you set a LoRA to 1.0 on one model and 0.4 on another.
- ☰ — drag this to move the LoRA to a different slot.
- ✕ — remove it.
At the bottom, a footer spells out exactly what each model will receive, in order — handy for confirming things are wired the way you think.
- Model routing — one row per model, each showing the checkpoint actually wired into it. Toggle a model's dot to include or exclude this LoRA from it.
- Per-model strength — each routed row has its own strength field. Leave them alone and they follow the chip's base strength, so changing the chip changes all of them. Type a value into one and that model breaks away and keeps its own — the base no longer drags it along. This is how you run a detail LoRA at 1.0 on the base pass and 0.4 on the refiner.
- Randomizer settings — for random slots only: roll, lock, auto-roll, and which folders this slot draws from.
- Remove lora.
New LoRAs start routed to every model at the base strength, so you only need to open this when you want something different.
Save a set of LoRAs and reload it later. The PRESET row sits just under the top strip.
- Save — names the current set and stores it. If the name's taken, it asks before overwriting rather than quietly replacing it. If you have random slots, it asks whether to keep them random or freeze them to whatever they rolled.
- Load — replaces everything: LoRAs, strengths, folder filter, and model count.
- + Add to stack — merges a preset's LoRAs into what you already have, leaving everything else alone. Duplicates are skipped, and if it won't all fit in 12 slots it tells you what didn't make it.
- ★ — favourite a preset so it pins to the top of the list.
- ⋮ — Overwrite with what's currently on the node, Rename, Duplicate, or Delete.
- The category dropdown groups presets however you like (by model, by project, by mood).
If you change anything after loading, the preset name turns orange italic and says "(modified)" so you know your current setup no longer matches what's saved. That covers everything a preset stores — the LoRAs, their order, strengths, enable states and routing, plus the folder filter and the model count.
Presets are files on disk in ComfyUI/user/fantastic-loras/presets/, so they're shared by every workflow and survive updates.
If you have hundreds of LoRAs, the FOLDERS bar narrows things down. Every node has one.
Click it to open the picker: type to search, use all / none for bulk changes, and ☆ star folders you use constantly so they pin to the top. Selected folders show as chips you can remove with ✕.
The filter controls what the LoRA picker offers and what the randomizer draws from, so the two never disagree. It's saved per node, with the workflow.
The picker shows your folders as an indented tree. Any folder with subfolders gets a ▣ / ▨ / ▢ branch toggle showing whether all, some, or none of the folders beneath it are enabled, with an on/total count — click it to select or clear that whole branch, at any depth. Clicking anywhere on a branch row cycles it: this folder and everything beneath it (▣) → just this folder (◧) → off (▢) → back again. A folder that holds no loras of its own skips the middle step, since there's nothing to select there. Folders that hold only subfolders show in italic, since there's nothing to select in them directly. Each branch has a ▾ / ▸ expander to fold it away, plus collapse all / expand all in the picker header — handy once you have a few levels of nesting. Collapsed branches are remembered across sessions. Searching switches to a flat list of full paths so matches are unambiguous.
Otherwise folders are exact: picking flux by name gives you LoRAs sitting directly in flux, not everything nested beneath it — use its branch toggle if you want the subfolders too.
🎲 Add random adds a slot that picks a LoRA for you. Great for discovering things you'd forgotten you had.
On the slot itself:
- 🎲 — roll a new LoRA right now.
- 🔓 / 🔒 — lock it to keep the current pick from changing. A locked slot's dice greys out.
- ⚙ → Randomizer — turn on auto-roll (a fresh pick every time you queue), or narrow which folders this slot draws from.
Per-slot folder scope is a subset of the node's folder filter — a random slot can never pull from a folder the node has filtered out.
Auto-roll picks the new LoRA when you hit Queue, so what you see on the node is what's about to be generated.
Some workflows run more than one model — a high and low pass, a refiner, or two checkpoints being compared. The chains control adds up to 5.
Each extra model gets its own MODEL input and output. There's a single CLIP input shared by all of them, and it stays optional — chains with no CLIP connected simply apply the model half of each LoRA. By default every LoRA feeds every model; use ⚙ → Model routing when you want a LoRA on only one of them, or at different strengths on each.
The Plotter uses the same slot grid as the loader, but the meaning changes: each slot is a test cell, not a layer. Add five LoRAs and you're asking for five images, each with one LoRA applied to the base model — not one image with all five stacked.
Wire MODEL into your sampler exactly like a normal loader, and CLIP too if your model uses it. The metadata output carries a label for each cell — send it to the Image Saver along with your generated images, and it does the rest.
The trick that makes this work in one queue: MODEL and metadata are list outputs. ComfyUI runs everything downstream once per item, so a 12-cell sweep runs your sampler 12 times off a single Queue press. You don't batch anything or re-queue by hand — but everything downstream of the Plotter does run 12 times, so a heavy upscale chain in that path costs you 12 upscales.
Fix your seed before you start. A comparison with a random seed per cell tells you nothing about the LoRAs, since you're also changing the noise.
Per-line runs each LoRA once, at whatever strength you set on its chip. Good for "which of these twelve do I actually like."
Global runs every LoRA at every strength in a shared list — this is the classic XY plot: LoRAs down the Y axis, strengths across the X. Set the list with 🎚 strengths (0.5, 0.75, 1.0). Chip strengths grey out in this mode, since the shared list is what's being swept.
Control image adds one cell with no LoRAs at all — the raw base model. It's the reference that makes everything else legible, and it's cheap. Leave it on.
🌐 Add Global Lora spawns and wires a Global Lora node: LoRAs there apply to every cell, on top of whatever's being tested. This is how you isolate one variable — hold your style and detail LoRAs constant while character LoRAs sweep. That node has its own two baseline toggles (pure base model, and globals-only), which take over from the Plotter's own control toggle while it's connected.
The Plotter carries the same chains control as the loader, with MODEL 2–MODEL 5 outputs. Each one runs the same sweep on a different checkpoint, so you can ask "how does this LoRA set behave on these two base models" and get both grids from a single queue.
Unlike the loader, there's no per-LoRA routing here — every LoRA is tested against every connected model, since the point is comparison. The M1 M2 … tags on each chip are telling you that, not offering a choice. The footer lists each chain with the checkpoint currently wired into it (or not connected), and the ⚙ modal shows the same list per LoRA along with its sweep strength.
The Image Saver composes everything into one image, in whichever style you prefer:
- Overlay — a modern look. Each cell keeps its own small label drawn in the corner, so cells stay self-describing however the grid is cropped or shared.
- Classic — the A1111-style XY grid. Cells stay clean and unmarked, with LoRA names printed down the left margin and strength values across the top. Needs a complete LoRA × strength rectangle, so use Global sweep mode; if the cells don't form a clean grid it falls back to Overlay and says so in the console.
Toggle with the 🖼 Grid mode button on the Image Saver.
The SWEEP footer does the arithmetic live: 4 lora lines × 3 strengths = 12 images + 1 control · 2 model chains. Read it before queueing. The multiplication gets away from people — six LoRAs at four strengths across two models is 48 generations plus baselines.
Internal class name FantasticPlotterImageSaver. Combines three nodes into one:
- LoRA Plot Image Saver — overlays a metadata label on each cell
- Image List to Image Batch (comfyui-impact-pack) — resizes cells to a common size and stacks them into a batch
- FL Image Batch To Grid (comfyui_fill-nodes) — composes the batch into a single grid image
Feed it your generated images and the Plotter's metadata output. It gives back a composed grid image for any Save Image node, and passes the individual cells straight through — so a Grid Viewer can hang off this node rather than re-tapping earlier wires.
The 🔍 Add Grid Viewer (connected) button drops a Grid Viewer beside the Saver with everything already wired.
| Widget | Default | |
|---|---|---|
| Constrain Image Output Size | Off | When on, each cell is scaled down so its longest side equals Max Cell Size before the grid is assembled. Useful when rendering many large images — keeps the final output a manageable size. |
| Max Cell Size | 768 | Longest side per cell in pixels (max 2048). Greyed out when Constrain is off. |
text_color |
white | Label text colour. |
background_color |
black | Label box background colour. |
font_size |
38 | Label font size in pixels. |
padding |
10 | Padding inside the label box and around the border labels in Classic mode. |
opacity |
1.0 | Opacity of the label box (Overlay mode only). |
images_per_row |
0 | 0 = auto (see below). Any positive value overrides. Ignored in Classic mode. |
single_strength_layout |
row | When every lora is tested at the same single strength (one image per lora), choose whether they lay out in one row or stack in one column. |
| 🖼 Grid mode button | Overlay | Toggles between the two layout modes (see below). |
Overlay (default): the metadata label is drawn as a semi-transparent box in the top-right corner of each cell image. The full grid is then composed automatically.
Classic (border labels): the A1111-style XY grid. Cells are kept clean, with lora names printed down the left margin and strength values across the top. This mode requires a complete lora × strength rectangle (i.e. Global sweep mode on the Plotter); if the metadata doesn't form a clean grid it falls back to Overlay with a console note.
When images_per_row is 0, the node reads the metadata list and counts the number of distinct strength values. That becomes the column count, so Global-mode sweeps automatically lay out as a true XY grid (loras = rows, strengths = columns) without any manual configuration.
One special case: when you're testing several loras at a single shared strength (so there's one image per lora and only one distinct strength), auto would otherwise put them all in a single column. By default (single_strength_layout = row), this case instead lays them out side by side in one row. Set it to column to revert to the single-column stack. It only affects this single-strength case — when strengths vary (already a row) or images_per_row is set, it does nothing.
Holds LoRAs that apply to every image in a comparison, on top of whatever the Plotter is testing. If you're comparing character LoRAs but always want your style LoRA active, it goes here — the characters vary, the style stays put.
It uses a simple row list rather than the slot grid: ➕ Add Lora, then one row per LoRA with an enable box, the name (click to swap), a strength field, and arrows to reorder. It has the same FOLDERS bar as every other node. There's no randomizer here — the list stays fixed for the whole run.
Each LoRA runs at its own fixed strength on every image. So with painterly at 0.8 and texture at 0.5, both apply at those strengths to every cell while the Plotter's own LoRAs sweep.
Each enabled lora runs at its own per-line strength (e.g., if you add painterly with strength 0.8 and texture with strength 0.5, both run at those fixed strengths on every swept cell). When connected to the Plotter's global_loras input, the Plotter's own stack loras sweep across their strengths while these globals stay constant.
The Global Lora node has two toggles (not but

0 comments
log in to comment.