๐พ Save Image Extended 2.88
The save node once you outgrow the default one
- images
Stock ComfyUI's Save Image node does exactly one thing: writes a PNG with a counter on the end. That's fine until you've generated a few thousand images across a dozen checkpoints and can't tell what's in output/ without opening each one. Save Image Extended is what people reach for the moment they actually care about organizing their output - it writes eleven image formats, builds folder trees from your workflow's own settings, and can log a JSON record of every job it saves. It's a reboot of an older node by thedyze, taken over and actively maintained by audioscavenger since mid-2024, and it's the node that regularly gets recommended on r/comfyui and r/StableDiffusion when someone asks "how do I get the LoRA name into my filename."
What it actually does. The node reads two comma-separated fields - filename_keys and foldername_keys - and resolves each entry against your workflow's live values. Put sampler_name, cfg, steps in there and your files come out named after the actual sampler, cfg, and step count used to make them. This isn't limited to a fixed list either: it reads any widget from any node in the graph, because it's just looking up field names in the same prompt object ComfyUI already builds for execution. If two nodes share a widget name - two KSamplers, say - it grabs the highest-numbered node's value by default, or you disambiguate explicitly with 12.sampler_name (turn on node badge IDs in Manager settings to see the numbers). You can also drop in datetime tokens like %F %H-%M-%S for POSIX-style timestamps, and / inside a key builds subfolders - ckpt_name/ will file images under a folder named after your checkpoint automatically.
The inputs that matter. images is the only required connection - wire your VAE Decode output here, same as any save node. Past that, filename_prefix is a fixed string tacked onto every file, filename_keys is the template described above, and output_ext picks the format: WebP by default, with AVIF, PNG, JPEG, JXL, JPEG2000, GIF, TIFF, and BMP all on the table. quality (0โ100, default 90) controls compression for the lossy formats - crank it to 100 and AVIF/WebP switch to lossless. save_metadata (on by default) is what embeds the prompt and workflow into the file so you can drag it back into ComfyUI later - leave it on unless you have a specific reason not to. Two optional string inputs, positive_text_opt and negative_text_opt, let you feed prompt text in explicitly for logging. There's no image or data output - this is a terminal node, is_output_node: true, nothing downstream to wire.
Everything else - foldername_prefix, delimiter, counter_digits, counter_position, one_counter_per_folder, save_job_data, job_data_per_image, job_custom_text, image_preview, named_keys - is there for when you want it and safely ignorable until you do. save_job_data is worth a special mention: set it above "disabled" and the node writes a jobs.json next to your images logging the prompt, sampler settings, and loaded models for every generation - genuinely useful if you're running batches and want a searchable log without opening EXIF data.
Installing it. Easiest path is ComfyUI Manager - search "Save Image Extended" and install. Manually: cd ComfyUI/custom_nodes && git clone https://github.com/audioscavenger/save-image-extended-comfyui, then restart ComfyUI. It needs numpy, pillow, pillow-avif-plugin, and pillow-jxl-plugin, all pulled automatically from its requirements.txt - nothing to download by hand, no model files.
Where people get tripped up. The big one: ComfyUI itself can only read embedded workflow metadata back out of PNG and WebP files. Save as AVIF, JPEG, or JXL and the prompt is still embedded in the EXIF tags - readable with exiftool - but you lose the drag-and-drop-to-reload convenience that's core to ComfyUI's workflow-sharing culture. If you want files you can hand to someone and have them just drop into the canvas, stick to WebP or PNG. Second: JXL and WebP both choke on very large images - WebP caps out around 12,000ร12,000px by design, and JXL will straight-up crash ComfyUI at that size, so don't reach for either on giant upscale outputs. Third, an older but real gotcha from the changelog: some custom nodes (notably pythongosssss's Custom-Scripts checkpoint loader) used to store widget values as a dict instead of a plain string, which broke the key-resolution logic - fixed in release 2.81, but if you're somehow on a very old pinned version and get a 'dict' object has no attribute error, that's the culprit. Last: the README flags it as incompatible with the separate extended-saveimage-comfyui node - that one only does WebP and is safe to remove if you've got this installed instead.
Inputs (19)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | โ | |
| filename_prefix | STRING | ComfyUI | Fixed string prefixed to file name |
| filename_keys | STRING | sampler_name, cfg, steps, %F %H-%M-%S | Comma separated string with sampler parameters to add to filename. * Example: `sampler_name, scheduler, cfg, denoise` Added to filename in written order. * Example: also accepts `vae_name` `model_name` (upscale model), `ckpt_name` (checkpoint). * `resolution` also works. * ANY parameter name of any node will work. The same applies to `foldername_keys` |
| foldername_prefix | STRING | Fixed string prefixed to subfolders | |
| foldername_keys | STRING | ckpt_name | Same rules as for `filename_keys`. Create subfolders by using `/` or `../` etc |
| delimiter | STRING | - | Any string you like. You can also use `/` to create subfolders |
| save_job_data | COMBO | disabled | Saves information about each job as entries in a `jobs.json` text file, under the generated subfolder. Multiple options for its content: `prompt`, `basic data`, `sampler settings`, `loaded models` |
| job_data_per_image | BOOLEAN | false | Saves individual job data file per image |
| job_custom_text | STRING | Custom string to save along with the job data | |
| save_metadata | BOOLEAN | true | Saves metadata into the image |
| counter_digits | INT | 40โ8 | Number of digits used for the image counter. `3` = image_001.png, based on highest number in the subfolder, ignores gaps. **Can be disabled** when == 0 |
| counter_position | COMBO | last | Image counter postition: image_001.png or 001_image.png |
| one_counter_per_folder | BOOLEAN | true | deprecated but I cannot remove it of all your saved prompts will break |
| image_preview | BOOLEAN | true | Turns the image preview on and off |
| output_ext | COMBO | .webp | File extension: WEBP by default, AVIF, PNG, JXL, JPG, etc |
| quality | INT | 900โ100 | Quality for JPEG/JXL/WebP/AVIF/J2K formats; Quality is relative to each format. * Example: AVIF 60 is same quality as WebP 90. * PNG compression is fixed at 4 and not affected by this. PNG compression times skyrocket above level 4 for zero benefits on filesize. |
| named_keys | BOOLEAN | false | Prefix each value by its key name. Example: prefix-seed=123456-width=1024-cfg=5.0-0001.avif |
| positive_text_optopt | STRING | Optional string saved as `positive_text_opt` in job.json when `save_job_data`=True | |
| negative_text_optopt | STRING | Optional string saved as `negative_text_opt` in job.json when `save_job_data`=True |
Outputs (0)
No outputs