markdown

measured markdown renderer powered by pretext. every block is measured before it hits the DOM — pure arithmetic, zero reflows.

plugins

each block type is a plugin that owns its measurement and rendering. core only handles paragraphs and headings.

headings & inline formatting

Heading 1

Heading 2

Heading 3

Regular paragraph with bold, italic, and strikethrough text. Inline code works too. Links like inference.sh are styled automatically.

Blockquotes can contain mixed formatting and work with the measurement engine — every line is measured, not estimated.

code blocks

typescript
interface MeasureStrategy {  kind: 'fixed' | 'computed'  height?: number  measure?: (width: number) => number}// Height = lines × lineHeight + chrome// No DOM needed — pure arithmeticfunction measureCodeBlock(code: string, lineHeight = 18) {  const lines = code.split('\n').length  return lines * lineHeight + 67 // header + padding + border}

tables

FeatureMeasuredPlugin
Paragraphspretext inline layoutcore
Headingspretext with font configcore
Code blockslines × lineHeight + chromecode-block
Tablesrows × rowHeight + headertable
Blockquotesrecursive with indentblockquote
Listsrecursive with indentlist
Imagesaspect ratio, max heightimage
YouTube16:9 aspect ratioyoutube
HRfixed 1pxhr

lists

Unordered:

  • Text measurement via pretext — pure canvas, zero DOM

  • Plugin system — blocks own their dimensions and rendering

  • Virtualizable — strategy heights feed directly into the virtualizer

Ordered with nesting:

  1. Parse markdown (remark + remark-gfm)

  2. Walk AST into layout IR (BlockNode / InlineItem)

  3. Measure:

    • Inline: pretext prepareWithSegments + layoutNextLine

    • Blocks: plugins handle their own height

  4. Render measured lines or fall back to flow mode

images & embeds

Images are zoomable — click to expand:

Mountain landscape

YouTube links auto-embed:


Horizontal rules are a 1px fixed-height plugin.

responsive

text reflows on width change. the component auto-measures its container via ResizeObserver.

Responsive reflow — drag the slider to resize. Text is re-measured via pretext on every width change. Code blocks, tables, and embeds adapt too.

typescript
// pretext measures text with canvas// zero DOM reads, zero layout thrashingconst prepared = prepareWithSegments(runs, font)let line = layoutNextLine(prepared, maxWidth)
FeatureResponsive
TextReflows via pretext
CodeScrolls horizontally
TablesOverflow scroll
ImagesAspect ratio preserved
  • List items reflow with the container

  • Bold and italic text stays on the correct lines

  • Inline code respects word boundaries

virtualized

measurement strategies feed directly into a virtualizer. only visible items are in the DOM.

0 total0 in DOM0px

installation

bash
npx shadcn@latest add https://ui.inference.sh/r/markdown.json