# answer-me-with-html: the model writes Markdown, a bundled CLI writes the page

> An agent skill that moves page construction out of the model and into a local renderer. Its headline token ratio does not match either of its own benchmark tables.

**QingYunA/answer-me-with-html** — Answer me with HTML - an agent skill that answers hard questions with a one-page HTML you can actually read.

- Repository: https://github.com/QingYunA/answer-me-with-html
- Stars: 4,248 · Forks: 284
- Language: JavaScript
- License: MIT
- Published: 2026-10-08 · Updated: 2026-10-08 · Language: en
- Canonical page: https://hysenlabs.com/projects/qingyuna-answer-me-with-html

## A skill that moves markup out of the model

The repository is a JavaScript package called answer-me-with-html, MIT licensed, with about 1,740 stars, 122 forks and 9 open issues, last pushed on 2026-10-06. The workflow it installs is short. You ask a question the way you normally would, the agent writes a brief Markdown draft, and a CLI turns that draft into a page on disk under `~/.answer-me-with-html/pages/`. The page carries theme and light and dark controls in its top-right corner and a button that copies the Markdown that produced it.

The manifest registers the same entry point under two names, `am` and `answer-me-with-html`, both pointing at `bin/am.js`, and it declares the package as ESM with `node >=20`. The README asks for Node.js 20 or newer and says there is no `npm install` step because the CLI is bundled inside the skill. The topics list tells you what kind of thing this is: `agent-skill`, `claude-code`, `claude-skill`, `diagram`, `explainer`, `ste100` and `llm` among twelve.

For Claude Code the install is a plugin add, which registers the skill as a marketplace entry:

```
/plugin marketplace add QingYunA/answer-me-with-html
/plugin install answer-me-with-html@answer-me-with-html
```

For everything else the documented path is a skill installer that asks which agents to write into, and the README says it covers more than 70:

```bash
npx skills add QingYunA/answer-me-with-html
```

## A 1/7 headline sitting next to a 6.1 times table

The claim at the top of the README is that the model writes about 1/7 of the tokens it would need to hand-write the HTML. Twenty lines later there is a table of measurements, and it says something different.

The setup is stated precisely: the same questions asked the same model both ways, in a plain Claude Code configuration, three topics and three runs each, medians, on Claude Sonnet 5.5. Output tokens go from 5,341 to 870, which the table labels 6.1 times fewer. Wall clock goes from 33 seconds to 12 seconds, and cost per answer from $0.092 to $0.067. A 6.1 times reduction is closer to 1/6 than 1/7, so the headline is a rounded figure that sits above the measured one rather than below it.

The video comparison diverges in the other direction. Asking for a 3Blue1Brown style page with no voice, the table reports 27,839 output tokens written page by page against 1,566 through `am video`, which is 17.8 times fewer, and 202 seconds against 17. The headline number describes neither table. It is closer to the text case and it understates the video case by a wide margin.

The README is upfront about the sample size for the video row. It says one topic and five runs, three by hand and two through the command, so read it as a rough size rather than a precise ratio. The caption under the comparison image adds another data point that does not match the table either: one run from an earlier benchmark in a heavily loaded setup, the same prompt and the same model, 9,351 output tokens for the plain page and 899 with the skill. That is 10.4 times, sitting between the two headline claims. Reproduction notes and per-topic numbers live in a `bench/` directory that the README links.

## Fifty milliseconds, or twelve seconds, depending on the clock

Right after the demo prompt the README says the page appears about 50 ms later. A few paragraphs down, the benchmark table reports 12 seconds. Both numbers are in the same document and they measure different things, which is worth spelling out because the difference is the entire argument for the project.

The 50 ms is the local render. Once the agent has handed over a Markdown draft, a Node process on your machine does the work: parse the Markdown, pick a template, lay out the diagram, check the prose, write one file. None of that consumes tokens and none of it waits on a model.

The 12 seconds is the wall clock for the whole answer, and the README explains why it is smaller than the 33 seconds of the direct approach. The model is not writing CSS, wrapper elements and SVG coordinates one at a time, so its output is shorter and it finishes sooner.

The practical consequence is that the skill moves the waiting rather than removing it. The render step was never the bottleneck, so the 50 ms figure does not mean the tool answers questions 240 times faster. What it means is that after the last token arrives, you are not waiting on markup generation. If your pain is the length of a wall of terminal text, the skill addresses that. If your pain is turn latency, the reduction is real but it is the 33 to 12 second figure that describes it, not the 50 ms.

## Cheaper in a plain session, more expensive in a loaded one

The cost row is the part of the README that deserves the most attention from anyone who already runs a heavily configured agent, because the same document reports opposite results.

In the plain setup the skill is described as 27 percent cheaper per answer, from $0.092 down to $0.067. Then the README explains the mechanism and admits the reversal. The skill adds two short turns to the conversation, and every turn re-reads the context. In a heavy setup, described as roughly 51,000 tokens of tools, rules and skills, the two extra turns cost more than the output tokens they save, and the author measured the skill at about 20 percent more expensive.

So the saving is not a property of the question. It is a property of your configuration. Output tokens only dominate the bill when the surrounding context is small enough that re-reading it twice is cheap. Once your context approaches the tens of thousands of tokens, per-turn overhead overtakes per-token generation savings.

This gives you a usable decision rule. Estimate the token count your agent loads on a normal turn, tools and rules included, and compare it against the 51,000 figure the README uses. Well below it, the token reduction on pages should dominate. Well above it, expect the extra turns to win, and the skill becomes a formatting preference rather than a saving. The README does not print a break-even point, so the honest summary is a direction and a threshold to compare against, not a number to plan around.

## No install step, next to two runtime dependencies

The README says plainly that there is no `npm install` step because the CLI is bundled inside the skill. The manifest in the repository root declares two runtime dependencies, `@dagrejs/dagre` at `^3.1.1` and `marked` at `^18.0.14`, plus `esbuild` and `yaml` as development dependencies. The dependency picture is not a contradiction once you separate the two audiences, but it does explain what the bundling claim is doing.

The `files` field ships `bin`, `src`, `skills` and `examples`, and the build script is a single Node invocation of `scripts/build.mjs`, which is what esbuild is for. The two runtime dependencies land in the bundle, which is why an end user who copies the skill folder has nothing to install. A contributor who clones the repository and runs the test suite does need those dependencies present.

The scripts also show what the project considers its own quality bar. Tests run on the built-in Node test runner with a 120 second per-test timeout, and the coverage script excludes the test and skills directories while demanding 85 percent line coverage, 85 percent function coverage and 80 percent branch coverage. There are separate scripts for an install smoke test, a snapshot pass and a release pass.

The tree backs up the multi-target claim. Alongside the source directories you find `.claude-plugin/`, `commands/`, `docs/`, `bench/` and a `package-lock.json`, so this is a working repository with a release pipeline rather than a folder of instructions. It also explains the badge that reads works with Claude Code, Codex, Cursor, OpenCode and Pi: the plugin route is documented only for Claude Code, while the installer and the manual copy instructions are what cover the rest.

For a manual install the README copies the skill folder into the agent's skills directory:

```bash
git clone --depth 1 https://github.com/QingYunA/answer-me-with-html.git /tmp/answer-me-with-html
cp -R /tmp/answer-me-with-html/skills/answer-me-with-html ~/.claude/skills/answer-me-with-html
```

The manifest version and the newest release tag agree here, both at 0.4.12, which is not always true of this kind of project and is worth checking on your own machine after an update.

## Language support that reads characters rather than intent

Version 0.4.12 moved language handling into one file per language under `src/languages/`, and its release notes describe the limits of that mechanism in unusually plain terms.

Traditional Chinese is detected from character forms. A draft tagged `lang: zh-TW`, `zh-Hant`, `zh-HK` or `zh-MO` gets Traditional page buttons, Traditional theme names and video player labels, and Traditional fonts placed ahead of the Simplified ones so a system whose default Chinese font is Simplified still draws the right glyphs. When no tag is present, the page is recognized by which characters are written in only one form, and the release notes state the failure case plainly: text made only of shared characters stays Simplified.

The same release adds Korean, Russian, Arabic, Hebrew, Thai and Greek detection so those drafts no longer come out labelled `zh-CN`. What it does not add is automatic detection for Latin-script languages, because those cannot be told apart by character shape. The notes tell you to declare `lang: fr`, or Spanish or Portuguese, explicitly, and a declared language with no label file of its own gets English labels while keeping its own `lang` attribute on the document. A tag is now written as declared, with `zh-tw` and `zh_TW` both normalized to `zh-TW`, while a bare `zh` still resolves to `zh-CN`.

The same release fixes a language leak in `am patch`, where patching a panel with plain text used to flip a Traditional page back to Simplified.

None of this translates anything. The renderer decides labels, fonts and the `lang` attribute; the words on the page are whatever the model wrote. A skill install is also not the only surface here, because the topic list and the README both carry the ASD-STE100 controlled-writing check, and 0.4.10 added a short Chinese word list covering common typo pairs, vague quantity words and the words above, below and within when they follow a number. The project treats readable prose as part of the deliverable, not only the diagram.

## Triggering decisions and a test suite that admits flakiness

The skill does not page every answer, and the README is specific about the boundary. Related concepts, multi-step flows and multi-way comparisons get a page. A one-line question such as how to show hidden files with `ls` gets a one-line answer. The mapping table lists what you can expect for a handshake question, a module map, a Redis against Memcached comparison, a paragraph critique, a Kubernetes timeline and a shell question, and you can also just ask for HTML directly in your own words.

Release 0.4.10 widened that boundary. The skill description now asks the agent to use it whenever a page would help more than plain text even if text would also work, naming state machines, diagnoses, review findings, trade-offs, decisions and any answer containing a table or a ranked list. The measured result comes from a local test of 19 prompts where the skill loaded in about 73 percent of runs, up from 54 percent. Small talk and explicit plain-text requests still do not trigger, and the author expects it to fire on some short answers now. A nineteen prompt local sample is enough to show direction and not enough to predict your own hit rate.

Testing is a mix of fast and slow layers, and the slow layer is a known problem. Version 0.4.11 says the Chrome tests fail less often and now say why when they do. That release also removed a separate always-on plugin and folded the behavior into one rule pasted into `~/.claude/CLAUDE.md` or `AGENTS.md`, with the old `always` setting in `config.json` ignored rather than treated as an error, and a note telling anyone who installed the old plugin to uninstall it so the reminder stops firing twice.

Regression safety for that refactor came from a snapshot pass: 432 combinations of render, video and patch reported no difference from the previous version. The theme system follows the same pattern of small external files, since a JSON file placed in `<AM_HOME>/themes/` is picked up like a built-in one and `am theme check` reports missing variables, invalid colors and low contrast.

## Conclusion

The design decision here is a good one and easy to state: the model spends its output budget on content, and a 50 millisecond local step spends nothing on markup. What the numbers around that decision do not settle is how much you save, because the README reports 6.1 times fewer output tokens in its table, roughly 1/7 in its headline, and 17.8 times for videos, on samples of three topics and one topic respectively. The cost direction flips with the size of your own agent setup, going from 27 percent cheaper in a plain session to about 20 percent more expensive once roughly 51,000 tokens of tools and rules are in context. Read those two numbers against your own setup rather than against the badge. Verify the install by checking the version in the bundled `package.json` against the newest tag, keep a habit of writing an explicit `lang` line for anything outside Chinese and the newly detected languages, and treat the always-on rule as configuration you own rather than a plugin you installed.

## FAQ

### What does the model actually produce when answer-me-with-html is active?

A short Markdown draft, nothing more. Templates, diagram layout, the STE controlled-writing check and the file writing all happen in the bundled CLI, which is why the README can claim the model spends a fraction of the tokens it would need to type the page by hand.

### Do I need to run npm install to use answer-me-with-html?

Not as an end user, because the CLI is bundled inside the skill folder you copy or install. The repository manifest does declare two runtime dependencies, dagre and marked, so anyone cloning the repo to run the test suite needs a dependency install first.

### When does this skill cost more instead of less?

When your agent loads a large context. The skill adds two extra turns and every turn re-reads context, so in a setup with about 51,000 tokens of tools, rules and skills the author measured it at roughly 20 percent more expensive than asking for HTML directly.

### How do I get Traditional Chinese labels on a generated page?

Tag the draft with `lang: zh-TW`, `zh-Hant`, `zh-HK` or `zh-MO`. Without a tag the renderer recognizes Traditional from characters written in only one form, and a draft made of shared characters stays Simplified, so declaring the language is the reliable route.

### Which coding agents can install this skill?

The badge names Claude Code, Codex, Cursor, OpenCode and Pi, and the README says the installer supports more than 70 agents. The documented Claude Code route is a plugin marketplace add, while other agents use `npx skills add` or a manual copy into their skills folder.

## Sources

- [Issues](https://github.com/QingYunA/answer-me-with-html/issues)
- [License: MIT](https://github.com/QingYunA/answer-me-with-html/blob/main/LICENSE)
- [QingYunA/answer-me-with-html on GitHub](https://github.com/QingYunA/answer-me-with-html)
- [README](https://github.com/QingYunA/answer-me-with-html/blob/main/README.md)
- [Releases](https://github.com/QingYunA/answer-me-with-html/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/qingyuna-answer-me-with-html
