Mustache Render
Render {{vars}} in any text, no chat call required
- vars
- text
The pack's chat nodes substitute {{var}} placeholders in your prompt for you. Mustache Render does the same substitution but as a standalone utility - text in, template filled out, no API call, no LLM involved. It's the plumbing between "I have a set of variables" and "I have a string I can use." Give it {{character}} is standing in {{location}} plus a vars dict, and it hands back Aiko is standing in a rain-soaked street.
What it accepts
The two inputs are text (the template) and vars. The interesting bit is the vars port: it accepts either the pack's SIMPLECHAT_VARS dict or a SIMPLECHAT_JSON object. That means you can wire it straight to the obj output of JSON Parse or JSON -> Vars without a conversion step - the renderer treats any mapping as its variable source.
There's also keep_unmatched (default on): when a placeholder has no matching variable, it's left as literal {{foo}} so you can see what wasn't filled. Flip it off and unmatched placeholders silently vanish, which is useful when you're intentionally templating a superset of your variables.
Why it exists separately
Because you often want a filled-in string before it ever reaches a chat node, or on a path that never touches one. Build a prompt by concatenating a template with variables from a JSON, then hand the rendered string to Chat, Chat with Image, or Gemini Image Gen. It also lets you reuse a Mustache-style template across the whole graph - the variable source feeds the render, the render feeds anything that takes a STRING. In an XY or batch setup, pair it with Text List (Batch): the list fans out, each item becomes a variable, and the render produces the per-item prompt.
Installing it
cd ComfyUI/custom_nodes
git clone https://github.com/Moeblack/ComfyUI-SimpleChat
Restart, or use Manager and search "ComfyUI-SimpleChat". Only dependency: aiohttp.
Gotchas
The substitution is a simple regex over {{ name }} - it's Mustache-style, not full Mustache. No sections, no loops, no conditionals, no {{#if}}. If you're coming from real Handlebars templates, leave the fancy syntax at the door; this handles flat variable replacement and nothing else. Values are stringified, so a nested object in your vars renders as its JSON text. And if keep_unmatched is on (the default), a typo in a var name is invisible - {{caracter}} just stays put in your prompt, so the LLM sees a literal placeholder. Check your output when something looks off; that's the most common silent failure here.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| text | STRING | — | |
| varsopt | SIMPLECHAT_VARS,SIMPLECHAT_JSON | — | |
| keep_unmatchedopt | BOOLEAN | true | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| text | STRING | — |