Ideogram 4 Prompt Builder (Luna)
Ideogram 4 won't take prose — draw the boxes instead
- image
- bboxes
- prompt
- preview
- bboxes
- width
- height
Ideogram 4 is a JSON snob. It was trained exclusively on structured JSON captions, so typing "a cozy cafe with a neon sign, one man reading at the window" in plain English gets you a model working at maybe half capacity. The workflow fix that saved its launch week was Kijai's prompt-builder node in KJNodes - you draw boxes on a canvas and it writes the caption Ideogram actually wants. This pack is a personal fork of that node with local-workflow additions bolted on, and it does the same core job: turn your layout into the JSON the model was built for.
If you've heard Ideogram 4 can hold exact composition and render real text in-image, this is the node that unlocks it. Its genuine superpower is precision - describe a box and the thing lands there - and once you're captioning in its native language, the results are worth the setup.
How it works
The node assembles a caption JSON shaped like Ideogram's documented schema: a high_level_description, an optional style_description (aesthetics, lighting, medium, color palette), and compositional_deconstruction with a background and an elements array. Each element is an object or text region - a type, a bounding box normalized to a 0–1000 grid as [ymin, xmin, ymax, xmax], a description, optional text, and a per-region color palette.
You never hand-write that JSON. You drag regions on the bundled canvas, click a box to describe it, tap swatches for palette colors, and the frontend serializes everything into the node's elements_data and style_palette_data inputs (managed by the UI, not you). The node then outputs the assembled string, a rendered preview of your boxes and labels, and pixel-space bounding boxes.
The inputs that matter
widthandheight- your canvas aspect ratio and the pixel grid the boxes are measured in. Ideogram 4 needs multiples of 16, so keep the step or the model gets confused.background- the scene description. The tooltip calls it required, and it is: this is what fills the space outside your boxes.style- a dynamic selector fornone,photo, orart_style, each revealing its own field. Pair withaesthetics,lighting, andmediumif you want a coherent style block.image- an optional reference image shown behind the editor, handy for tracing a layout.import_json+import_mode+verbatim_passthrough- the Luna fork's real additions. Wire in an existing caption JSON and it seeds the editor (or stays authoritative), andverbatim_passthroughemits it byte-for-byte, preserving fields and key order the editor doesn't model. Great for hand-edited or API-sourced captions you don't want mangled.require_labels- blocks the run if any region has no description, so an unlabeled box can't slip through to Ideogram.pause_for_edit/pause_timeout- halt the queue at this node, adjust boxes, hit Continue. Leavepause_timeoutat 0 and it waits forever, which is exactly as dangerous as it sounds.
Outputs: prompt (the JSON caption string - this is what wires into the Ideogram 4 sampler's caption input), preview (an IMAGE of your layout), bboxes (pixel-space BOUNDING_BOX dicts for SAM or crop nodes), plus width and height so downstream nodes can stay consistent.
Installing it
Via ComfyUI Manager, search ComfyUI-Ideogram4-Luna. Or the manual way:
cd ComfyUI/custom_nodes
git clone https://github.com/lunaaispace-eng/ComfyUI-Ideogram4-Luna
Restart ComfyUI, then hard-refresh the browser with Ctrl+F5 - this is in the README for a reason. The editor lives in the pack's own web/ directory, and your browser will happily serve a stale copy of the frontend JavaScript if you don't. Add it under Add Node → Luna → Ideogram → Ideogram 4 Prompt Builder (Luna).
No model files download with this node - it only builds captions. You still need the Ideogram 4 weights (fp8 or nf4, both fitting a 24GB card), and mind the non-commercial license before selling anything rendered with them.
Where people get burned
- The editor is missing or looks broken - almost always the browser cache. Ctrl+F5, or restart with a fresh tab.
- Prose prompts underperform - that's the model, not the node. This whole pack exists because of it. Use boxes.
- The grey refusal image - Ideogram trained its safety filter into the weights; ComfyUI's lead dev had to publicly disclaim it as not a ComfyUI bug. Structured JSON prompting (the format Ideogram documented first) reportedly clears it, and this node is how you do that cleanly.
- Verbatim passthrough silently doing nothing - it only fires when
import_jsonis wired and parses as valid JSON. Bad JSON gets dropped without an error, and the editor drives output instead.
If you already run KJNodes, the original Ideogram4PromptBuilder sits in your menu too. They don't collide - the Luna fork just adds the passthrough mode, bbox outputs, and pause/edit/continue loop. Pick one and get to boxing.
Inputs (20)
| Name | Type | Default | Description |
|---|---|---|---|
| width | INT | 102464–16384 | Canvas aspect width (also the pixel grid the bbox is measured in). Ideogram 4 needs multiples of 16. |
| height | INT | 102464–16384 | Canvas aspect height (also the pixel grid the bbox is measured in). Ideogram 4 needs multiples of 16. |
| high_level_description | STRING | Optional one-line overview of the whole image (blank = omitted). | |
| background | STRING | Required scene background description. | |
| style | COMBO | 3 options: [object Object], [object Object], [object Object] | |
| aesthetics | STRING | Style descriptor (blank = omitted). | |
| lighting | STRING | Style descriptor (blank = omitted). | |
| medium | STRING | Style descriptor (blank = omitted). | |
| style_palette_data | STRING | Serialized style color palette from the editor (managed by the node UI). | |
| elements_data | STRING | Serialized regions from the editor (managed by the node UI). | |
| bg_brightness | INT | 250–100 | Background image brightness % (managed by the node UI slider). |
| import_mode | COMBO | when empty | How a wired import_json is used: 'when empty' only seeds the editor while it has no regions (then the editor wins, so you can edit); 'always' makes the wired JSON authoritative so its changes always propagate to the output. |
| output_format | STRING | compact | Output JSON formatting (set via the editor toolbar): 'compact' (default, what Ideogram 4 expects) or 'pretty' (indented, for readability). |
| imageopt | IMAGE | Optional reference image shown as the editor background (and behind the preview). | |
| import_jsonopt | STRING | Optional: a full caption JSON. When connected, it loads into the editor and drives the output per 'import_mode'. | |
| verbatim_passthroughopt | BOOLEAN | false | When a JSON is wired to import_json, output it EXACTLY as received (preserves structure, key order, and any fields the editor doesn't model). The editor still loads it for viewing. Turn off to let the editor drive output. |
| require_labelsopt | BOOLEAN | false | Block the run if any region has no description, so an unlabeled box can't reach Ideogram. |
| pause_for_editopt | BOOLEAN | false | Halt the workflow at this node so you can edit the layout, then click Continue to resume. Off = run straight through. |
| pause_timeoutopt | INT | 00–86400 | Seconds to wait while paused before auto-continuing. 0 = wait forever. |
| bboxesopt | BOUNDING_BOX | [object Object] | Optional pixel-space boxes ({x, y, width, height}) used to seed the editor's regions when it has none. Ignored once regions exist. |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| prompt | STRING | — |
| preview | IMAGE | — |
| bboxes | BOUNDING_BOX | — |
| width | INT | — |
| height | INT | — |