May 25, 2026

Let the model ship the controls

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.

Make me a pricing card for our Pro plan.

Here's the plan card, billed at . The accent color is and the button reads .

Pro
$29/ mo
  • 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:

What the model generates
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>
What is rendered

Here's a stat card for showing , with a change of .

Monthly revenue
$24,500
+12%

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:

Show me a physics demo I can play with.

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:

Chart our quarterly revenue.

Here's a chart showing in . The values are in Q1, in Q2, in Q3, and in Q4, totaling $280k.

Revenue
total $280k
100
75
50
25
0
$65k
Q1
$80k
Q2
$45k
Q3
$90k
Q4

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:

Theme modified