WaveSpeedAI Image Generation
“Image Generation” Is a Lie — This Node Edits Pictures on WaveSpeedAI’s Servers
- image1
- image2
- image3
- image
- image_path
- generation_info
- generation_time
The name is a lie. WaveSpeedAI Image Generation doesn't generate anything from a prompt - it edits. The image1 input is required, and if you don't feed it a picture the node throws "At least one image input is required." What it actually does is ship up to three images, your prompt, and an optional LoRA to WaveSpeedAI's hosted qwen-image/edit-plus-lora endpoint, then pull the result back into your graph. If you went in expecting a txt2img box, that's your first trap. If you wanted a Qwen-style image editor without a GPU, this is the whole point.
Why you'd reach for it: Qwen image editing is a genuinely strong multi-image editor - show it two or three reference shots and tell it what to change. Running that class of model locally costs real VRAM; WaveSpeedAI runs it on their boxes and you pay per generation. Same deal the pack's FAL nodes make, just a different provider. The flip side is worth stating plainly: you're trading control for convenience. An API can reprice or change its filters overnight, and a file on your disk can't.
How it works
The node converts your image tensors to base64 data URIs, POSTs them with the prompt and size to api.wavespeed.ai, gets back a request id, then polls the result endpoint every two seconds until it reads completed. Then it downloads the image and returns it as a normal ComfyUI IMAGE tensor. Everything else is bookkeeping: it saves a copy to ComfyUI's temp directory, writes a metadata JSON into temp/wavespeed_metadata/, and hands you four outputs - image, image_path, generation_info (a JSON string of the request params and the API's full response), and generation_time.
The inputs that actually matter
api_key- paste your WaveSpeedAI key, or setWAVESPEED_API_KEYand it pre-fills.prompt- your edit instruction.image1- wire this from a Load Image node. Without it, the node refuses to run.width/height- default 886×1182 (portrait), step 8, min 64, max 4096. Match your source image's aspect ratio or you'll get awkward resizing.
That's 90% of it. image2 and image3 are optional reference shots. lora_url wants a hosted LoRA - a direct download URL, not a local file path - and lora_scale (default 0.84) controls how hard it applies. seed is -1 for random; set a positive one to reproduce a result. output_format is jpeg/png/webp, default jpeg - fine for previews, but pick png if you're going to feed the result back into another edit.
Install
Install the pack, not the node. ComfyUI Manager → search "Node_Fun_ComfyUI", or:
cd ComfyUI/custom_nodes
git clone https://github.com/nofunstudio/Node_Fun_ComfyUI
cd Node_Fun_ComfyUI
pip install -r requirements.txt
Then restart ComfyUI. No model downloads - the model lives on WaveSpeedAI's servers, so the pack's requirements.txt only pulls in replicate and fal-client (for the sibling nodes). The WaveSpeedAI nodes themselves just use requests and PIL, which ship with ComfyUI.
Where people get burned
- Outputs go to the temp directory, not
output/. The README says so, and temp gets wiped on restart. Theimage_pathoutput is the only reliable way to find the file, so save anything you like. - It's a paid API. WaveSpeedAI is a real service - it launched in early 2025 marketing itself as the fastest FLUX-dev host - but the billing drew grumbles: late-2025 threads complained about minimum credit purchases. Budget before you batch a queue.
- Failures are silent. The error path returns
Noneforimage, which can kill whatever's downstream. If nothing appears, read thegeneration_infooutput - the error text lives there. - The async footgun. Reading the source: the node's worker is an
async def, and ComfyUI's executor calls node functions synchronously and never awaits them. Every API node in this pack shares the pattern. As shipped that can fail with a coroutine error in the console - it's a young, single-commit pack and this is beta-grade code. If you hit that, you're not doing anything wrong; check for a newer version before debugging your workflow.
Inputs (11)
| Name | Type | Default | Description |
|---|---|---|---|
| api_key | STRING | — | |
| prompt | STRING | A beautiful painting | — |
| image1 | IMAGE | — | |
| width | INT | 88664–4096 | — |
| height | INT | 118264–4096 | — |
| image2opt | IMAGE | — | |
| image3opt | IMAGE | — | |
| lora_urlopt | STRING | — | |
| lora_scaleopt | FLOAT | 0.840–2 | — |
| seedopt | INT | -1-1–2147483647 | — |
| output_formatopt | COMBO | jpeg | 3 options: jpeg, png, webp |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| image_path | STRING | — |
| generation_info | STRING | — |
| generation_time | STRING | — |