JAS OpenRouter Text to Image [set OPENROUTER_API_KEY]
GPT Image or Nano Banana via OpenRouter
- images
Here's the node for people who don't want to maintain two API keys and two billing accounts just to reach two closed models. It's a text-to-image wrapper that talks to OpenRouter, and one dropdown swaps the backend between openai/gpt-5.4-image-2 and google/gemini-3.1-flash-image-preview - the model behind Nano Banana 2. Both bill through your single OPENROUTER_API_KEY. No OpenAI key, no Gemini key, no Comfy account, no Comfy credits. Just OpenRouter.
This is the aggregation play, and it's genuinely handy if you're already routing LLM traffic through OpenRouter. Same dashboard, same billing line, same key for your text and your images. The flip side is you're going through a middleman's chat-completions-style endpoint rather than the providers' native image APIs, so some provider-native niceties don't survive the trip.
How it works
The node POSTs a chat request to openrouter.ai/api/v1/chat/completions with modalities: ["text", "image"]. Your prompt goes in as user content, your system_prompt becomes a system message, and aspect_ratio and quality are packed into image_config. A nonzero seed goes into the payload. The returned image is decoded back into a standard IMAGE tensor and flows into Save Image or whatever comes next.
One thing worth knowing: the aspect_ratio dropdown includes source, but that choice only makes sense on the edit node, where there's an input image to derive it from. Here, with no image, source is just passed upstream and it's on the model to shrug or comply - stick to the explicit ratios for text-to-image.
The inputs that matter
- prompt - the whole job, multiline.
- model - the OpenAI-or-Google dropdown.
- aspect_ratio - the standard ladder from 1:1 to 21:9 (default 1:1).
- quality - low/medium/high, default medium. This is your cost-and-time lever.
- system_prompt - defaults to "generate a high-quality image that follows the user's prompt closely." Bake style guidance in here and keep the prompt field for content.
Output is a single images tensor. A common pattern: drop this into a workflow as the hero generator, then hand the result to a local upscaler - these are draft-speed models, and an upscale pass is cheap next to another API call.
Installing it
One of six nodes in the comfyui_jas_nodes pack. ComfyUI Manager: search "comfyui_jas_nodes". By hand:
cd ComfyUI/custom_nodes
git clone https://github.com/reducm/comfyui_jas_nodes
cd comfyui_jas_nodes
python -m pip install -r requirements.txt # only dependency is `requests`
Then set the key and restart ComfyUI from the shell that launches it:
export OPENROUTER_API_KEY="your-key"
No model files, no VRAM, no provider dashboards.
Common issues
The standard first failure is the key missing from ComfyUI's environment - instant OPENROUTER_API_KEY is not set, and it's always "wrong shell," not a bug. After that, the README's debugging section is your friend: if you get text back instead of an image, the model refused the request or answered in text only; the node surfaces that honestly rather than hiding it. Remember your prompt leaves your machine, lands at OpenRouter, and then passes to the provider's own filter - the node can't override what either of them refuses, and per-call cost applies every single time you hit Run. For "both closed giants behind one key," though, this is the simplest route on the board.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| prompt | STRING | — | |
| base_url | STRING | https://openrouter.ai/api/v1/chat/completions | — |
| model | COMBO | openai/gpt-5.4-image-2 | 2 options: openai/gpt-5.4-image-2, google/gemini-3.1-flash-image-preview |
| aspect_ratio | COMBO | 1:1 | 11 options: source, 1:1, 2:3, 3:2, 3:4, 4:3, +5 |
| quality | COMBO | medium | 3 options: low, medium, high |
| seed | INT | 00–2147483647 | — |
| system_prompt | STRING | Generate a high-quality image that follows the user's prompt closely. | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| images | IMAGE | — |