People increasingly ask LLMs for artifacts instead of text. A chart instead of a table. A portfolio simulator instead of advice. A map instead of an address. HTML turns out to be unreasonably effective for this: ask for a visual and the model hands back something you can interact with.
Until you want to change something. Adjust the price, swap a color, rename a label, and you're back in the chat asking for a new version.
What if the model could just say "here's what you might want to tune" without being asked? I've been calling this pattern inline controls. For example, this post is themed in with body text at in mode. Try clicking any value.
The idea
Typed, interactive controls the model declares inside its own response. It picks which values are worth adjusting, chooses the right control type, and emits both the rendered HTML and its controls in a single shot.
Here's the plan card, billed at . The accent color is and the button reads .
- Unlimited projects
- Priority support
- Custom integrations
Click any highlighted value. The card updates instantly. You never talked to the model again.
The format
Two things ship in the response. <control> tags declare each adjustable value. An <html> block defines the component, referencing those controls by name:
Here's a stat card for <control id="label" type="text" default="Monthly revenue" /> showing <control id="value" type="text" default="$24,500" />, with a change of <control id="change" type="slider" default="12" min="-30" max="50" suffix="%" />. <html> <div style="padding: 16px; border: 1px solid #e5e7eb; border-radius: 8px;"> <div style="font-size: 12px; color: #6b7280;">{controls.label}</div> <div style="font-size: 24px; font-weight: 600;">{controls.value}</div> <div style="color: {controls.change >= 0 ? '#10b981' : '#ef4444'}; display: flex; align-items: center; gap: 4px;"> <svg width="12" height="12" viewBox="0 0 12 12" fill="none" style="transform: rotate({controls.change >= 0 ? '0deg' : '180deg'})"> <path d="M6 10V2m-3 3l3-3l3 3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /> </svg> {controls.change >= 0 ? '+' : ''}{controls.change}% </div> </div> </html>
Here's a stat card for showing , with a change of .
The rendering layer parses both, wires the prose up with controls, and renders the HTML using the current values.
Control types
"slider": numeric value with a range"number": numeric input with optional min/max"color": color picker rendered as a swatch"text": free-form text input"switch": binary toggle, both options visible inline"select": dropdown for many options
Interactive components
Same applies to more complex, interactive components. Ask for a physics demo and the controls steer it as it runs:
Sure, here's a small physics simulation. Gravity is set to with elasticity. The balls are and wide. Adjust any value to see the effect:
Data and dashboards
Same idea for analytics. Adjust the numbers, color, and chart type inline:
Here's a chart showing in . The values are in Q1, in Q2, in Q3, and in Q4, totaling $280k.
In the wild
We already use a version of this at faces.app, where every slide is generated as code. The model embeds inline controls directly in its response so users can tweak content and design without round-tripping back to the LLM: