mdlib-pure

Plugins

Each plugin is its own entry point: import only what you use. Sizes are measured at build time like npm run size: minified, gzipped, with the core counted once (plugins are measured without it). mdlib-pure/element is the exception: it bundles the core and every plugin, and is measured whole.

mdlib-pure/gfm

Adds tables, task lists, footnotes, strikethrough, autolinks, alerts.

Import
import { gfm } from 'mdlib-pure/gfm'
Use
createMarkdown({ plugins: gfm() })
Size
3.92 KB min + gzip
Syntax
GitHub Flavored Markdown: | a | b | tables, ~~strike~~, www. and URL autolinks, - [ ] task lists, [^1] footnotes, > [!NOTE] alerts, and the tag filter for html: true
AST
table { align } › tableRow › tableCell, delete, footnoteReference, footnoteDefinition, footnotes, taskCheckbox, alert { kind }
Reference
API reference: mdlib-pure/gfm

Each part is also exported on its own, and gfm({ footnotes: false }) turns one off:

Part Syntax AST gzip
table() ` a b
strikethrough() ~~text~~ or ~text~ delete 0.15 KB
autolink() www.x.com, https://…, emails link 1.34 KB
tasklist() - [ ] and - [x] items listItem.checked, taskCheckbox 0.37 KB
footnotes() [^label] and [^label]: text footnoteReference, footnoteDefinition, footnotes 1.25 KB
tagfilter() with html: true, neutralizes <script>, <iframe>… (changes html nodes) 0.22 KB
alerts() > [!NOTE], [!TIP], [!IMPORTANT], [!WARNING], [!CAUTION] alert { kind } 0.49 KB

Markdown

| Plugin | Syntax |
|:--|:--|
| gfm | ~~old~~ new |

- [x] done
- [ ] todo

See www.commonmark.org.[^1]

> [!NOTE]
> An alert.

[^1]: A footnote.

Result

Plugin Syntax
gfm old new
  • done
  • todo

See www.commonmark.org.[^1]

Note

An alert.

mdlib-pure/headings

Adds heading ids, permalinks, table of contents.

Import
import { headings, toc } from 'mdlib-pure/headings'
Use
createMarkdown({ plugins: [headings({ permalink: true })] })
Size
0.56 KB min + gzip
Syntax
none: a transform over existing headings. GitHub-compatible slugs, duplicates get -1, -2…; prefix: 'user-content-' for untrusted input
AST
sets heading.id; toc(root) returns { depth, id, text }[]
Reference
API reference: mdlib-pure/headings

Markdown

## Install

### With npm

## Install

Result

Install #

With npm #

Install #

Table of contents

toc(md.parse(src))
// [ { "depth": 2, "id": "install", "text": "Install" }, { "depth": 3, "id": "with-npm", "text": "With npm" }, { "depth": 2, "id": "install-1", "text": "Install" } ]

mdlib-pure/container

Adds ::: container blocks.

Import
import { container } from 'mdlib-pure/container'
Use
createMarkdown({ plugins: [container()] })
Size
0.81 KB min + gzip
Syntax
::: kind Title … :::, nestable with longer fences (::::)
AST
container { kind, title, children } → <div class="md-container md-container-KIND">
Reference
API reference: mdlib-pure/container

Markdown

::: warning Before you publish
Run `npm run verify`.
:::

Result

Before you publish

Run npm run verify.

mdlib-pure/math

Adds $inline$, $$display$$ and $$ blocks.

Import
import { math } from 'mdlib-pure/math'
Use
createMarkdown({ plugins: [math()] })
Size
0.94 KB min + gzip
Syntax
$…$ (pandoc rules: $5 and $6 stays text), $$…$$ in a paragraph, $$ fenced blocks; output works as-is with KaTeX auto-render or MathJax
AST
inlineMath { value, display? }, math { value, meta }
Reference
API reference: mdlib-pure/math

Markdown

Inline $e^{i\pi} + 1 = 0$, and a block:

$$
\int_0^1 x^2 \, dx = \frac{1}{3}
$$

Result

Inline \(e^{i\pi} + 1 = 0\), and a block:

\[\int_0^1 x^2 \, dx = \frac{1}{3}\]

mdlib-pure/mermaid

Adds ```mermaid diagrams, no dependency on Mermaid.

Import
import { mermaid, renderMermaid } from 'mdlib-pure/mermaid'
Use
createMarkdown({ plugins: [mermaid()] }) · await renderMermaid(el, { load: () => import('mermaid') })
Size
1.49 KB min + gzip
Syntax
fenced code blocks with the info string mermaid (as on GitHub and GitLab); renderMermaid() loads Mermaid only when a page has diagrams, uses securityLevel: 'strict', colors them from the --md-* tokens and redraws them when the color scheme changes
AST
mermaid { value } (replaces the code node)
Reference
API reference: mdlib-pure/mermaid

Markdown

```mermaid
flowchart LR
  md[Markdown] --> mdlib[mdlib-pure] --> svg[Diagram]
```

Result

flowchart LR
  md[Markdown] --> mdlib[mdlib-pure] --> svg[Diagram]

mdlib-pure/deflist

Adds definition lists.

Import
import { deflist } from 'mdlib-pure/deflist'
Use
createMarkdown({ plugins: [deflist()] })
Size
1.22 KB min + gzip
Syntax
Term on one line, : Definition below (Pandoc and PHP Markdown Extra style)
AST
definitionList { spread } › definitionTerm, definitionDescription { spread }
Reference
API reference: mdlib-pure/deflist

Markdown

Parser
: Turns lines into blocks, then text into inlines.

Renderer
: Turns the tree into HTML or DOM.

Result

Parser
Turns lines into blocks, then text into inlines.
Renderer
Turns the tree into HTML or DOM.

mdlib-pure/mark

Adds ==highlight==.

Import
import { mark } from 'mdlib-pure/mark'
Use
createMarkdown({ plugins: [mark()] })
Size
0.13 KB min + gzip
Syntax
==text==, with the flanking rules of *
AST
mark { children } → <mark>
Reference
API reference: mdlib-pure/mark

Markdown

This is ==very== important.

Result

This is very important.

mdlib-pure/frontmatter

Adds YAML and TOML front matter.

Import
import { frontmatter, getFrontmatter } from 'mdlib-pure/frontmatter'
Use
createMarkdown({ plugins: [frontmatter()] })
Size
0.57 KB min + gzip
Syntax
--- (YAML) or +++ (TOML) on the first line, up to the closing line; not rendered
AST
yaml { value } or toml { value }, first child of root; getFrontmatter(root) returns { type, value } | null
Reference
API reference: mdlib-pure/frontmatter

Markdown

---
title: Hello
---
# Body

Result

Body

Reading it

getFrontmatter(md.parse(src))
// {"type":"yaml","value":"title: Hello"}

mdlib-pure/adapter

Adds React, Preact and Vue elements.

Import
import { toElements } from 'mdlib-pure/adapter'
Use
toElements(md.toVNodes(src), createElement, 'react')
Size
0.53 KB min + gzip
Syntax
none: converts VNodes with the framework’s own h/createElement; presets react, preact, vue
AST
no node: works on the VNodes of md.toVNodes()
Reference
API reference: mdlib-pure/adapter

Markdown

**Rendered** by React 19 at build time.

Result (React SSR)

Rendered by React 19 at build time.

mdlib-pure/element

Adds the <mdlib-markdown> viewer and the <mdlib-editor> editor with live preview, as Web Components.

Import
import { defineElements } from 'mdlib-pure/element'
Use
defineElements({ loaders }) · <mdlib-editor plugins="all" value="# Draft">
Size
20.19 KB min + gzip, core and every plugin included
Syntax
every plugin on this page, chosen per element with plugins="gfm math" or plugins="all"; KaTeX and Mermaid through loaders, fetched only when a document uses them; raw HTML and functions only through named configs, never from attributes; styles in mdlib-pure/editor.css
AST
no node of its own: getMarkdown(plugins, config) returns the instance behind an element, to parse() its text
Reference
Guide: Web Components

HTML

<mdlib-markdown class="md" plugins="gfm" source="
| Element | For |
|:--|:--|
| `mdlib-markdown` | reading |
| `mdlib-editor` | writing, with a live preview |"></mdlib-markdown>

Result (what the element renders, here at build time)

Element For
mdlib-markdown reading
mdlib-editor writing, with a live preview

mdlib-pure/entities

Adds the full HTML entity table, for Node, SSR and workers.

Import
import { decodeEntity } from 'mdlib-pure/entities'
Use
createMarkdown({ decodeEntity })
Size
10.75 KB min + gzip
Syntax
named entities such as &frac12; or &hearts; outside the browser (in browsers the core decodes them through the DOM)
AST
no node: decoded entities become text
Reference
Getting started: Node, SSR, workers

Markdown

Half: &frac12;, love: &hearts;, copyright: &copy;

Result

Half: ½, love: ♥, copyright: ©

Outside the browser

<!-- Node, default decoder -->
<p>Half: &amp;frac12;, love: &amp;hearts;, copyright: &amp;copy;</p>
<!-- Node, with decodeEntity -->
<p>Half: ½, love: ♥, copyright: ©</p>

Write your own

A plugin is a plain object with block, inline, delimiters, transform and render fields. AGENTS.md explains how to choose the extension point and has a recipe for each; templates/plugin in the repository is a complete, tested plugin to copy. It is written so that an AI agent can follow it: see For AI agents.