JSON Prompt Generator
It doesn't generate prompts — it writes a letter to your LLM asking for one
- prompt_to_llm
The name is a small lie, and it's worth getting straight before you download anything. JSON Prompt Generator doesn't generate a prompt and it certainly doesn't output JSON. It assembles a request - your natural-language description, a system prompt, and an empty JSON template - and hands that string to an LLM, which then writes the actual JSON prompt. Think of it as a pre-written cover letter that makes whatever LLM you're running produce exactly the structured prompt you want.
Why bother? Because on the current crop of models the text encoder is an LLM. Anima, Chroma, Flux 2 Klein, Z-Image - they read your prompt as an instruction, not as a bag of tags. So having a local LLM translate "street portrait, casual, soft morning light" into a well-structured block of JSON is two machines speaking the same language. JSON gives clean field separation, which matters when you have several characters with several attributes each and plain prose keeps bleeding them together. It's not magic - a good paragraph does the same work - but the structure keeps things from blurring.
How it works
Everything this node does is string concatenation, pure stdlib, no network. The text_description you type gets glued to your chosen camera settings (as a JSON block), the pack's system_prompt, and a JSON template, all pulled from config.json inside the pack folder. The result comes out the single output, prompt_to_llm, a STRING.
Wire that into an Ollama generate node or a Gemini node - the pack doesn't bundle either, so you need a separate node pack and, for Ollama, a local server (ollama serve, default http://127.0.0.1:11434). The LLM replies with JSON wrapped in markdown fences, which is where the pack's second node (LLM Output Formatting) takes over.
The inputs that matter
Only one is yours to really think about:
- text_description - the multiline box where you describe the image in whatever natural language you like. The placeholder cheerfully suggests Chinese, because the author's example workflow is in Chinese and the whole pack leans that way. English works fine.
The other six - lens, aperture, metering, orientation, crop, angle - all default to "SET BY AI", and that's the right default. Leave them alone and the LLM fills the template's photography fields from your description. Set one if you genuinely care ("I want 85mm f/1.4") and it gets injected as a hard constraint into the request. These aren't guesses on my part; they're parsed straight out of config.json into the widget dropdowns at load time.
The one big caveat: the template is hardcoded to a street-portrait, East Asian aesthetic, restrained retouching look. Run it blind and everything comes out samey. If that's not your thing, edit template and camera_settings in config.json and restart ComfyUI. That's the whole point of the file being editable.
Install
ComfyUI Manager is easiest - search "JSON Prompt" (pack title ComfyUI-JSON-Prompt) and install. Or do it by hand:
cd ComfyUI/custom_nodes
git clone https://github.com/fr0nky0ng/ComfyUI-JSON-Prompt
Restart ComfyUI. Then find JSON Prompt Generator under Utils/Text.
Good news on dependencies: requirements.txt is empty and the node imports only json, os and re. No models to download, no torch wheels, no API key bundled. The real dependency is invisible - you need an LLM node (like comfyui-ollama) and a running model, because this node is useless without one.
Common issues
- You connected
prompt_to_llmto a text encoder and got garbage. Of course you did. That output is a request, not a prompt. It must go to an LLM first; the JSON prompt only exists after the LLM responds. - Everything looks the same across runs. See the template caveat above. Edit
config.json, or varytext_descriptionharder - the LLM only fills what you describe or what it can infer. - The dropdowns don't match the README. The README is vague about options; the widgets are generated from
config.jsonat load, so what you see is whatever that file says. Reload ComfyUI after editing. - It only pays off on LLM-encoded models. If your checkpoint is Illustrious or Pony, you want comma-separated booru tags, not JSON blocks - this node's format is aimed at the 2026 encoder generation.
Tiny pack, nine impressions, no community chatter - but if you're running an LLM-encoder model and hate hand-writing structured prompts, it's a clean little tool. Just remember it's the middleman, not the answer.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| text_description | STRING | — | |
| lens | COMBO | SET BY AI | 8 options: SET BY AI, wide-angle prime (24mm), wide-angle prime (28mm), wide-angle prime (35mm), standard prime (50mm), portrait prime (85mm), +2 |
| aperture | COMBO | SET BY AI | 9 options: SET BY AI, f/1.4, f/2.0, f/2.8, f/4.0, f/5.6, +3 |
| metering | COMBO | SET BY AI | 8 options: SET BY AI, balanced exposure with natural contrast, evaluative metering for overall scene balance, center-weighted average for subject emphasis, spot metering for precise highlight control, partial metering for central subject isolation, +2 |
| orientation | COMBO | SET BY AI | 3 options: SET BY AI, horizontal, vertical |
| crop | COMBO | SET BY AI | 9 options: SET BY AI, full-body, upper body, waist-up, three-quarter body, mid-thigh, +3 |
| angle | COMBO | SET BY AI | 11 options: SET BY AI, eye-level, high-angle downward, low-angle upward, bird's-eye view, worm's-eye view, +5 |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| prompt_to_llm | STRING | — |