diff --git a/docs/content/1.getting-started/0.introduction.md b/docs/content/1.getting-started/0.introduction.md index 0057a7d..7370f21 100644 --- a/docs/content/1.getting-started/0.introduction.md +++ b/docs/content/1.getting-started/0.introduction.md @@ -29,7 +29,11 @@ This is an important message! :: ``` -The `::alert` is a block component that supports properties and children (also known as slots). Learn more about the [Component Syntax](/syntax/components). +The `::alert` is a block component that supports properties and children (also known as slots). + +::tip{to="/kb/why-comark"} +Learn why we created Comark and the principles behind its design in [Why Comark](https://github.com/kb/why-comark). +:: Comark parses this into an [AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree) that can be rendered to [HTML](/rendering/html). It also supports rendering to [Vue](/rendering/vue), [Nuxt](/rendering/nuxt), [React](/rendering/react), and [Svelte](/rendering/svelte), turning your Markdown into fully interactive content. diff --git a/docs/content/7.kb/0.why-comark.md b/docs/content/7.kb/0.why-comark.md new file mode 100644 index 0000000..7d819cb --- /dev/null +++ b/docs/content/7.kb/0.why-comark.md @@ -0,0 +1,129 @@ +--- +title: 'Comark: From Markdown to Interactive UI' +description: Markdown is human-readable, token-efficient, and AI-native. Comark extends it to interactive components with runtime parsing, multi-framework rendering, and first-class streaming. +navigation: + title: Why Comark? +links: + - label: Comark Syntax + icon: i-lucide-file-text + to: /syntax/components + color: neutral + variant: soft + - label: Installation + to: /getting-started/installation + color: neutral + variant: soft + icon: i-lucide-download +--- + +Markdown won the authoring war. But it stops at document structure: headings, lists, code blocks, emphasis. No components, no interactivity. Comark picks up where Markdown ends. + +## Why Markdown? + +Every piece of web content serves two audiences: +- **Humans** who need scannable prose +- **Machines** who need predictable structure + +HTML is powerful but verbose. That verbosity costs even more in an era where AI agents pay per token. JSON is structured but no one wants to write a blog post in it. + +**Markdown occupies rare middle ground.** The source text is comfortable prose for a human author and token-efficient structured data for a machine consumer. That convergence wasn't part of [Gruber's original design](https://daringfireball.net/projects/markdown/). He was solving for readability in 2004. But it explains why Markdown has become the default format for both human authoring and AI consumption. + +### Why Machines Prefer Markdown + +The evidence is clearest in token economics. + +The same page served as HTML versus Markdown to an AI agent can use **80% fewer tokens** in Markdown form. At scale, that is not a formatting preference, it is an infrastructure decision. Lower token counts mean faster responses, lower costs, and longer effective context windows. + +Beyond token count, Markdown's explicit structure maps cleanly to how language models reason. A `##` heading is unambiguously a section boundary. HTML carries the same information buried in `

` but the signal-to-noise ratio is far worse. + +### AI as a First-Class Audience + +The tooling industry has converged on this conclusion. [Streamdown](https://github.com/vercel/streamdown) (an open-source renderer by Hayden Bleasel, DX Engineer at Vercel) was built precisely because LLMs stream token by token and existing renderers like `react-markdown` assume a complete document, making them unable to handle unterminated blocks gracefully. Because LLMs tend to produce Markdown by default, Streamdown is a React component designed to render it correctly as chunks arrive — pairing naturally with `useChat` and other streaming patterns from `@ai-sdk/react`. Together they reflect a deliberate recognition that AI agents are now a _primary_ consumer of content, not a secondary one. + +The same shift is visible in developer tooling. Files like `AGENTS.md` and `.cursorrules` are Markdown documents that configure AI coding assistants. GitHub Copilot reads them across sessions. Cursor injects them into every prompt. Claude Code uses `CLAUDE.md`. The format that humans write is the same format that machines act on. + +This is new. For most of computing history, human-authored content and machine-readable configuration were different artifacts in different formats. Markdown is collapsing that boundary. + +## Why Comark? + +Standard Markdown has no way to express a warning callout, a tabbed code group, a video embed, or a pricing card. The current workarounds each come with a cost. + +**Raw HTML works**, but it immediately breaks the plain-text readability that makes Markdown valuable and reintroduces the token overhead that Markdown removes for AI. + +**MDX** made Markdown programmable, but at a cost: `.mdx` files are compiled to JSX at build time. Shipping new content means triggering a rebuild and a redeploy. Your content becomes code, locked to a build pipeline. + +Comark takes a different position. Component syntax should stay in plain text, parsing can happen at build time or runtime, your choice, and work across any renderer. That is the design constraint every other decision follows from. + +### Built on Five Years of MDC + +Comark is the next generation of [MDC](https://github.com/nuxt-content/mdc), the parser that has powered [Nuxt Content](https://content.nuxt.com)'s component syntax for over five years. MDC proved the concept. Comark extends it in three directions. + +**AI models stream token by token.** Comark's [auto-close](/api/auto-close) parser renders correctly at every incomplete frame, no buffering, no broken UI. Use `` to pipe AI-generated Markdown directly into your component tree as chunks arrive, including interactive components rendered in real time. + +**Payloads should be small.** Instead of verbose object trees, Comark produces compact nodes `['tag', props, ...children]` that reduce serialization size when the AST travels over the wire or included during server-side rendering. The same philosophy that makes Markdown token-efficient for LLMs, applied to the JavaScript runtime. + +**Content should outlast frameworks.** The same `.md` source renders to Vue, React, Svelte, Nuxt, plain HTML, and ANSI terminal output. No rewrite when you switch stacks. + +### Markdown as Data, Not Code + +Comark's component syntax is a superset of standard Markdown, inspired by the [Markdown directives proposal](https://talk.commonmark.org/t/generic-directives-plugins-syntax/444), a CommonMark effort to standardize a generic extension point without breaking parsers. + +```mdc +::alert{type="warning"} +This action cannot be undone. +:: +``` + +Still plain text. No bundler, no compiler step. A human reads it and understands it. An AI agent parses it as structured data: a component named `alert` with a `type` attribute and text content. + +**That shift makes Markdown data, not code.** Because `parse(markdown)` is a pure function returning a [Comark AST](/syntax/comark-ast), the full CMS pattern becomes possible: + +1. A database, CMS, or headless service stores the raw Markdown, components included +2. On request, the server runs `parse(markdown)` and gets the compact AST +3. The AST is sent to the client +4. `` renders it by looking up each tag name in a components map at runtime + +No build step between authoring and rendering. Content is live the moment it is saved. + +::tip +A more efficient way would be to store the AST directly in the database and use the [`renderMarkdown(ast)`](/api/render) when having to display Markdown. +:: + +### First-Class Slots + +Where HTML breaks down is **slots**: placing rich Markdown content into named regions of a component. In Comark, slots are first-class citizens. `#slotname` markers let you compose full Markdown into any named region: + +```mdc +::hero +#title +Build UIs from **Markdown** + +#description +Comark parses component syntax at runtime — no compiler, no rebuild. +Supports Vue, React, Nuxt, and Svelte out of the box. + +#cta +[Get started](/getting-started) +:: +``` + +This is still Markdown. Readable in a text editor, parseable by a machine, renderable by any framework. + +### One Source, Every Renderer + +MDX is tied to React. The original MDC was tied to Nuxt. Most Markdown renderers are locked to a single output target. Comark decouples parsing from rendering entirely. + +The same `.md` source file renders to: + +- [`` in Vue](/rendering/vue) — async components, streaming, slot-based composition +- [`` in React](/rendering/react) — Server Components and client-side rendering +- [`` in Nuxt](/rendering/nuxt) — zero-config module with auto-imports and Nuxt UI integration +- [`` in Svelte](/rendering/svelte) — snippets and streaming +- [`renderHTML()` in @comark/html](/rendering/html) — server-side HTML strings, RSS, emails, static builds +- [`renderANSI()` in @comark/ansi](/rendering/ansi) — styled terminal output for CLIs + +Your content outlasts your framework choice. + +--- + +Markdown gave humans and machines a shared language. Comark makes it interactive. Write once, render anywhere, stream in real time.