Framework-agnostic HTML to Markdown content negotiation for web responses.
web-markdown lets your app keep serving normal HTML by default, and serve Markdown only when a
client explicitly asks for it with Accept: text/markdown.
No duplicate templates. No crawler workflow. No behavioral change for normal browsers.
- Receive request and inspect
Accept. - Decide whether markdown is explicitly acceptable.
- If eligible, capture HTML response body (bounded by size limits).
- Convert HTML to Markdown with a pluggable converter.
- Return response with preserved status/cache semantics and merged
Vary: Acceptheader.
- AI agents and tooling often consume Markdown better than raw HTML.
- Most production apps already render HTML and should keep doing that.
- Content negotiation is the right HTTP mechanism for representation changes.
A typical blog page payload is roughly 500KB as HTML/CSS/JS and about 2KB as Markdown (around 99.6% smaller).
Exact savings vary by page, but this shows how much
representation overhead can be removed, allowing agents to work faster and hit limits less often.
- Explicit negotiation only (
Accept: text/markdownwith satisfiableq). - HTML remains the default behavior.
Vary: Acceptis always merged to protect caches.- Core logic is reusable; adapters stay thin.
- Crawling/scraping websites.
- Maintaining parallel Markdown templates.
- Altering normal
text/htmlbehavior for regular browser traffic.
| Package | Description |
|---|---|
@web-markdown/core |
Accept parsing, Vary merging, HTTP helpers, shared path matching utilities. |
@web-markdown/transform-fetch |
Fetch Request/Response transformation pipeline with gating + observability. |
@web-markdown/converters |
Default HTML to Markdown converter (content mode, front matter, URL rewriting hooks). |
@web-markdown/adapters-express |
Express middleware adapter. |
@web-markdown/adapters-next |
Next integration primitives (manual wiring for App Router and Pages Router). |
@web-markdown/adapters-fastify |
Fastify onSend hook adapter (experimental). |
@web-markdown/adapters-koa |
Koa middleware adapter (experimental). |
@web-markdown/adapters-node-http |
Node http/https adapter for custom servers (experimental). |
Shipped today:
- Express adapter package.
- Next integration primitives package.
- Fastify adapter package (experimental).
- Koa adapter package (experimental).
- Node
http/httpsadapter package (experimental).
Planned adapter-package candidates:
- Nuxt/Nitro (
h3)
Frameworks where docs + core packages are usually enough:
- Remix
- Astro
- SvelteKit
- Hono
- Cloudflare Workers / Bun / Deno fetch runtimes
Decision criteria and framework-by-framework rationale:
/docs/integration-strategy.md
- Docs index
- Architecture overview
- HTTP semantics and caching contract
- Integration strategy and adapter roadmap
- Adapter authoring contract
- Express integration guide
- Next integration guide (App + Pages)
- Fastify integration guide
- Koa integration guide
- Node http/https integration guide
- Remix integration recipe
- Astro integration recipe
- SvelteKit integration recipe
- Hono integration recipe
- Converter behavior and options
- Quickstart and common patterns
| Adapter | Command |
|---|---|
| Express | pnpm --filter @web-markdown/playground-express start |
| Fastify | pnpm --filter @web-markdown/playground-fastify start |
| Koa | pnpm --filter @web-markdown/playground-koa start |
| Node http/https | pnpm --filter @web-markdown/playground-node-http start |
| Next App Router | pnpm --filter @web-markdown/playground-next-app-router dev |
| Next Pages Router | pnpm --filter @web-markdown/playground-next-pages-router dev |
pnpm install
pnpm test
pnpm smoke:playgrounds
pnpm typecheck
pnpm lint
pnpm build