Save Image + Metadata JSON
Save the recipe next to every PNG, not just inside it
- images
- metadata_json
ComfyUI's stock SaveImage already embeds the workflow into your PNG, and that's genuinely great - it's why "drag the image back onto the canvas" reconstructs the whole graph. But that embedded metadata has two weak spots: re-encode the file (Discord, image apps, resizing all do this) and it's gone, and it's a pain to actually query later. Save Image + Metadata JSON (class MSV_SaveImageWithMetadataJson, from the Metadata Saver Viewer pack) is the drop-in replacement that fixes both: every PNG you save also gets a matching .json file written next to it, holding the full prompt, workflow, and a readable summary.
Reach for it when you're building a generation log you'll actually search later - dataset collection, A/B testing prompts, keeping a per-image record that survives being re-saved by anything. The PNG still gets the workflow embedded (keep that on for drag-back restore), so the sidecar is a bonus, not a replacement.
How it works
Swap it in where you'd put SaveImage. It takes your images batch and, for every frame, writes the PNG and a sidecar .json in the same output folder. The JSON uses a compact layout with three parts:
summary- a Fooocus-style quick-read:Prompt,Negative Prompt,Sampler,Scheduler,Seed,Steps,Guidance Scale,Denoise, plus Base Model, CLIP Model, VAE, and each LoRA with its weight. These are inferred from the graph, so they work even if you never named them.raw- the full ComfyUIprompt,workflow, and remainingextra_pnginfo, untouched.workflowlives once underraw.workflow, not duplicated insideextra_pnginfo.image- filename, subfolder, and batch index, so a multi-image batch is traceable.
The detail work is where this node earns its keep. For PerSampleLoraLoader it records only the LoRA name and the weight actually used for that saved frame's batch index (the full settings stay in raw.prompt), and it resolves range_step_by_batch mode using the batch index and the latent's batch_size - matching the runtime linspace behavior. Model/LoRA/VAE entries that are present in the prompt but not connected to the saved image get flagged used: false and a (unused) suffix, so the summary tells you the truth about what that image was actually made with, not what's merely sitting in the graph. And strings over 50,000 characters get collapsed into a {length, sha256, preview} placeholder, which stops a text-preview node from feeding the JSON back into the next prompt and growing the metadata recursively forever.
The inputs that matter
filename_prefix- supports subfolders and date/time tokens, e.g.%date:yyyy-MM-dd%/my_project_. Saves toComfyUI/output/2026-05-14/my_project_00001_.pngplus its.json.embed_png_metadata(defaultTrue) - keep this on so dragging the PNG back into ComfyUI restores the workflow.save_sidecar_json(defaultTrue) - flip off if you only want embedded metadata and no extra files.
The single output, metadata_json (STRING), carries the JSON for the last image in the batch - wire it to a ShowText node if you want the recipe visible right in the UI.
Install
Search "Metadata Saver Viewer" in ComfyUI Manager, or:
cd ComfyUI/custom_nodes
git clone https://github.com/bbc-s/metadata-saver-viewer
Then restart ComfyUI. There's no requirements.txt and the pyproject declares zero dependencies - it's plain Python on top of the Pillow/NumPy/torch you already have, so install is genuinely one step and there's nothing to break.
Gotchas
Files land in ComfyUI/output by default - if you want them somewhere saner, bake the subfolder into filename_prefix. If the summary looks "wrong," check the used flags before assuming a bug: it's usually a node that's present in the graph but bypassed from the image path. And don't panic if a giant prompt shows up in the JSON as a sha256 placeholder - that's the 50k compaction doing its job, not data loss. The full string is still in your workflow; it just isn't duplicated into the file.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | — | |
| filename_prefix | STRING | ComfyUI | — |
| embed_png_metadata | BOOLEAN | true | — |
| save_sidecar_json | BOOLEAN | true | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| metadata_json | STRING | — |