| name | html-artifacts |
| description | Produce a single self-contained HTML file instead of a markdown document when the deliverable is spatial, comparative, interactive, or long-lived. Use this skill aggressively — agents undertrigger here. Trigger on requests for implementation plans, PR writeups, code reviews, module maps, architecture explanations, design systems, component sheets, prototypes (animations or click-throughs), SVG figures, flowcharts, slide decks, feature explainers, concept explainers, status reports, weekly updates, incident post-mortems, retrospectives, and throwaway editors (triage boards, flag toggles, prompt tuners, anything draggable). Trigger on phrasings like "write me a plan", "review this PR", "explain how X works in this repo", "compare these approaches", "show me design directions", "prototype this interaction", "give me a deck", "write a status update", "draft a post-mortem", "make me a triage board", "lay out the options". Trigger when the natural markdown output would exceed roughly 200 lines, or would contain three or more of {comparison table, diagram, multiple alternatives, time-ordered events, color or type tokens, embedded code samples, inline mockups}. Do NOT trigger for short factual answers, single-file code edits, conversational replies, code review of a single function, pure prose under 200 lines, or anything the user explicitly asks to keep as plain text or markdown. When in doubt and the deliverable is something the user will read more than once, default to HTML. |
html-artifacts
When the natural output is a long markdown document, a single self-contained .html file usually serves the reader better. The reader skims, points at things, exports the result, and keeps the file. Markdown gets pasted once and lost.
Source of the pattern: Thariq Shihipar, The unreasonable effectiveness of HTML (https://thariqs.github.io/html-effectiveness/). Twenty reference demos cover every category in the trigger map below.
Decision prompt: markdown or HTML?
Run this checklist before producing the deliverable. If two or more answers are yes, ship HTML.
- Will the output be longer than roughly 200 lines of markdown?
- Does it contain a comparison, multiple alternatives, or a side-by-side?
- Does it contain a diagram, flowchart, architecture sketch, or any spatial relationship?
- Does it contain a timeline, schedule, milestones, or time-ordered events?
- Does it contain design tokens (colors, type, spacing) that the reader will copy?
- Does it contain interactive content (toggles, sliders, drag-drop, click-through, animations)?
- Will the user open this file again later, share it, or print it?
- Is the user explicitly asking for a deck, dashboard, prototype, post-mortem, or status report?
Two or more yes answers means HTML. Zero or one yes answers means markdown is probably correct.
If the user explicitly asks for markdown, plain text, a code block, or "keep it short", produce that instead. The decision prompt is a default, not an override.
Trigger map
| Work type | What HTML gives the reader that markdown does not |
|---|
| Exploration, planning | Alternatives placed next to each other on one page; a real timeline you can scan |
| Implementation plan | Milestones on a timeline; a data-flow diagram; the risky code inline; a risk table |
| Code review, PR writeup | Annotated diff with margin notes, severity tags, jump links |
| Module map, architecture | Boxes and arrows with the hot path highlighted |
| Design system | Live swatches; real type scale; copy-from spacing tokens |
| Component sheet | Every size, state, and intent of one component on one page |
| Prototype | The actual easing curve; the actual click-through |
| Diagram, flowchart | Inline SVG with click-to-expand steps and timing labels |
| Slide deck | Arrow-key nav; no Keynote; no export step |
| Feature explainer | TL;DR box; collapsible request-path steps; tabbed config snippets |
| Concept explainer | Live demo, comparison table, hover-linked glossary |
| Status report | What shipped, what slipped, a small chart, a colored timeline |
| Incident post-mortem | Minute-by-minute timeline; log excerpts; follow-up checklist |
| Throwaway editor | Drag-drop board, toggle grid, slider playground; copy-state-as-markdown button |
What good looks like
- One file. All CSS and JS inline. No build step. Opens by double-clicking.
- Pick one styling system: Tailwind via CDN, or vanilla CSS. Do not mix.
- No external assets except fonts (Google Fonts
<link>) and icons (Lucide CDN or inline SVG). No images unless the user supplied them.
<meta name="viewport" content="width=device-width, initial-scale=1"> always present. Layout works on a phone.
- Interaction is included only where it earns its keep. Sliders for an easing curve, drag for a triage board, click-to-expand for steps. Decoration is not interaction.
- Always include an export. A copy-to-clipboard button that turns the page state back into markdown, JSON, or a diff, so the user can paste into the next prompt.
- Print-friendly.
@media print rules so the file works as a PDF.
- Sentence-case headings. Plain visible prose. Do not stylize away from clarity.
What to avoid
- React, Vue, Svelte, or anything that needs a build step.
localStorage and sessionStorage inside claude.ai artifacts (not supported there). On disk they are fine.
- Heavy chart libraries when an inline SVG bar chart of 30 lines does the job.
- Default Bootstrap or shadcn-without-customization output. Pick a deliberate aesthetic.
- Lorem ipsum. If the user did not supply content, say so and ask.
- Fake interactivity. A button that does nothing is worse than no button.
Surface-specific output
Claude Code or any agentic CLI session: Write the file to the repo or a scratch directory. Print the absolute path so the user can open it. If the file is part of a series, prefix with 01-, 02-.
claude.ai chat (artifacts on): Ship as a single text/html artifact. Inline everything. Skip localStorage (use React useState or in-memory JS variables).
API / programmatic: Return the HTML as a single string in the response, with the filename in a sibling field if the schema supports it.
Workflow
- Run the decision prompt above. If markdown wins, stop and produce markdown.
- Identify which row of the trigger map matches the request.
- Open the matching demo at https://thariqs.github.io/html-effectiveness/ to anchor the visual reference. Note the layout, the interactive element, and the export.
- Sketch the structure: sections, the spatial element (timeline, diagram, sheet, board), the export.
- Write the file. Inline CSS and JS. Apply the user's writing rules to every visible string.
- Verify before delivering: does the viewport meta tag exist, does the export work, does it print cleanly, does it look like more than default Bootstrap, does the prose follow the user's style preferences?
Examples
Example 1 — yes, HTML
Input: "Write me an implementation plan for migrating our Selenium tests to Playwright."
Output: 01-selenium-to-playwright-plan.html with milestones on a timeline, a flow diagram of the migration phases, an inline risk table, and a "copy plan as markdown" export button.
Example 2 — yes, HTML
Input: "Explain how rate limiting works in this codebase."
Output: rate-limiting-explainer.html with a TL;DR box at the top, collapsible sections for each step in the request path, tabbed code snippets for the three relevant config files, and a glossary in the margin.
Example 3 — yes, HTML
Input: "Compare three approaches for handling auth in our app."
Output: auth-approach-comparison.html with three columns side by side, a trade-off table at the bottom, and a "pick one" button that exports the chosen approach as a paragraph for the implementation prompt.
Example 4 — no, stay in markdown
Input: "What's the difference between useMemo and useCallback?"
Output: A short markdown answer in the chat. Two-paragraph answer, no file.
Example 5 — no, stay in markdown
Input: "Fix this typo in line 42 of README.md."
Output: A single-line edit. No skill involvement.
Example 6 — no, stay in markdown
Input: "Write a haiku about deployment day."
Output: A haiku in chat. Creative writing under 200 lines and not a deliverable the user will reopen.