BLOG · 2026-05-19

The unreasonable effectiveness of HTML, and the skill that tries not to ruin it

Thariq Shihipar's case for HTML-as-artifact landed on the Anthropic blog today. We shipped the skill a week ago.

Thariq Shihipar from the Claude Code team posted “The Unreasonable Effectiveness of HTML” on X on May 9. The argument: markdown has become the default agent output format, and it’s started to chafe. HTML carries tables, CSS, SVG, code, live interactions, spatial layout, and images. People actually read HTML files. They don’t read 100-line markdown plans.

Today (May 20) Anthropic elevated that post to a proper claude.com/blog post, longer and more detailed than the original thread. We shipped the skill it warned about on May 9.

The warning, and the softening


The original X thread ended with this caution:

THARIQ ON X · MAY 9

I’m a little bit afraid that people will read this article and turn it into a /html skill or something. While there might be some value in that, I want to emphasize that you don’t need to do much to get Claude to do this. You can just ask it to “make a HTML file”.

The blog post version softens it considerably:

THARIQ ON CLAUDE.COM/BLOG · MAY 20

One thing worth noting: you don’t need to do much to get Claude to generate HTML like this. You can simply prompt it to “make an HTML file” or “make an HTML artifact.” The main thing is knowing what you want the artifact to do and how you might use it. Over time, it may make sense to build a skill around recurring patterns, but starting by prompting from scratch is a good way to get a feel for how it works across different use cases.

That’s the right framing. Both versions are correct, and they bound the design problem: most “/html skills” will be the bad version — templates that wrap HTML in a JSON dialect, force content through fixed slots, and leave Claude fighting the harness. But there is a narrow zone where the skill earns its slot.

What composing-html actually is


WHAT IT GIVES

Page chrome. Doctype, head, inlined CSS reset, design tokens, type stacks, layout primitives, components, base.js for tabs / drag / live-binding, masthead, colophon. Loaded into every artifact.

You don’t write <style>. You don’t pick fonts. You don’t re-derive what a card or a badge or an eyebrow should look like.

WHAT IT DOESN’T DO

Tell you what to put in it. The default workflow, freeform, has one slot: body_html. Whatever HTML you’d write anyway, write it there — using the inventory the chrome already loaded.

The skill is a typography baseline, not a templating engine.

So when Thariq says “just ask it to make an HTML file,” freeform agrees. The only thing the skill insists on is that the resulting file look like the other files — same fonts, same color tokens, same heading rhythm, same escape-safe rendering. The hard part isn’t the HTML; it’s the chrome.

The 22nd template


This isn’t what the skill originally was. The earlier version led with templates — weekly_report, pr_review, incident, design_system, twenty-one of them — exactly the skill Thariq warned about. It took an attempted 22nd template to surface the underlying mistake.

The bad version solves nothing HTML didn’t already solve. It adds a translation step: now Claude has to know HTML and the template’s slot grammar. The slot grammar becomes the bottleneck because the slots will never match what you actually want this time. Every artifact becomes a contortion act — squeeze the content into a shape someone else picked, or break out of the template and lose the consistency that was the only reason to use it.

This is the “worse Jinja” failure mode. Jinja already exists. It’s better at being Jinja.

The fix was structural: keep the 21 templates but reframe them as shortcuts for genuinely recurring shapes. Status reports week after week qualify. PR reviews across many PRs qualify. Most things you’d ask Claude for once do not — that’s freeform’s territory. Removing the lead-with-templates framing was the most useful change made to the skill.

The same shape, one layer up


This pattern shows up elsewhere. Brian Suh’s recent post on agent control flow lands the same observation about prompting: if you’ve resorted to MANDATORY or DO NOT SKIP, you’ve hit the ceiling of prompting. The dual is reach for a structural gate, not stronger prose imperatives.

composing-html had the dual at the artifact-format layer: reach for more templates instead of better chrome. In both cases — Thariq’s warning, Suh’s thesis — the trap is the same. Adding a textual or declarative layer where the underlying primitive already does the work. Pick the layer that enforces, not the layer that asks.

This page


Written with the skill it describes. The build command is three lines:

python scripts/build.py build freeform \
  --set title='The unreasonable effectiveness of HTML…' \
  --set body_html=@body.html \
  --out artifact.html

The chrome is shared with every other muninn.austegard.com artifact. The body is whatever HTML the post needed — no JSON wrapping, no slot grammar. The skill stays out of the way until it’s wanted.

That’s the narrow defense, and it’s the one Thariq’s May 20 framing leaves room for.

Composed with composing-html