LZ Pipe Pack
The bundle that turns twenty wires into one
- model
- clip
- vae
- positive
- negative
- latent
- lz_pipe
If you've ever stared at a shared ComfyUI workflow and lost the thread - model, clip, VAE, positive, negative, latent, width, height, steps, cfg, seed, each dragged across the whole canvas as its own wire - LZ Pipe Pack is the antidote. It bundles the entire generation state into one LZ_PIPE object that travels down a single connection, and every other node in this pack's pipe system knows how to pull off what it needs and push back what it changed.
This is the same "context object" pattern rgthree's Context, Efficiency Nodes, and ComfyUI-Easy-Use each reinvented. ComfyUI-LZNodes just does it with a slightly smaller surface: pack here, unpack there, merge in the middle. Nothing about it generates images by itself - it's pure bundling, which makes it the natural starting point for a pipe-based workflow.
What goes in
Every input is optional, which is the first thing beginners find surprising. You can wire in just a MODEL and a couple of strings and it'll happily pack that. The fields, from the schema:
- Model plumbing:
model,clip,vae - Conditioning:
positive,negative(the encodedCONDITIONINGobjects) - Text and geometry:
positive_text,negative_text,width,height - Provenance:
ckpt_name,ckpt_hash,lora_name,lora_strength - Latent:
latent
The string and integer inputs are forceInput - you can type into them or wire a string/int node into them, whichever the workflow needs. The output is a single lz_pipe.
Why you'd actually use it
The classic flow in this pack is: LZSimpleCheckpointLoader or EZCheckpointLoader → LZPipePack → LZKSamplerDecode (the all-in-one sampler/decode node) → LZSaveImageAndLog. The pipe carries the checkpoint, its hash, and the prompts from the loader; the sampler reads what it needs; the save node writes it all into a log file. Three nodes, one wire between them, and the entire generation recipe is recoverable at the end.
Because the pipe is just a dict, any node in the system can read or write keys and hand the updated bundle along. That's also the trap: stale context. If you unpack model off a pipe that was assembled before you applied a LoRA, you'll silently run the base weights and probably blame the model. The wire that made the graph legible also hides which version of each value is inside it. When you're actively debugging a value, unpack it and look at it directly.
Installing it
It's part of the ComfyUI-LZNodes pack:
cd ComfyUI/custom_nodes
git clone https://github.com/liz-ils/ComfyUI-LZNodes
Restart ComfyUI (or use Manager → search "ComfyUI-LZNodes"). No extra Python dependencies and no model downloads - the whole pack runs on what stock ComfyUI already ships.
One honest caveat
The LZ_PIPE type is this pack's own invention, so a workflow that adopts it is married to the pack. Your graph becomes much easier to read, but it won't plug into a pipe built by another pack - and it's a lot harder to trace than plain wires when something goes wrong. That trade is fine once you've decided to commit to the LZNodes style; just know you're committing. If you want to test the bundle, wire LZPipeUnpack on the end and confirm what actually rode along before you trust it downstream.
Inputs (16)
| Name | Type | Default | Description |
|---|---|---|---|
| modelopt | MODEL | — | |
| clipopt | CLIP | — | |
| vaeopt | VAE | — | |
| positiveopt | CONDITIONING | — | |
| negativeopt | CONDITIONING | — | |
| latentopt | LATENT | — | |
| positive_textopt | STRING | — | |
| negative_textopt | STRING | — | |
| widthopt | INT | — | |
| heightopt | INT | — | |
| ckpt_nameopt | STRING | — | |
| ckpt_hashopt | STRING | — | |
| lora_nameopt | STRING | — | |
| lora_strengthopt | STRING | — | |
| lora_modelopt | STRING | — | |
| lora_weightopt | STRING | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| lz_pipe | LZ_PIPE | — |