Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/remarkjs/remark/llms.txt

Use this file to discover all available pages before exploring further.

Out of the box, remark parses and serializes CommonMark — the standardized, unambiguous specification of markdown. CommonMark covers the essential constructs: paragraphs, headings, lists, links, images, code, and emphasis. Anything beyond that — strikethrough, tables, footnotes, YAML front matter, LaTeX math, JSX — requires a plugin. This design keeps the core lean and predictable while letting you opt in to exactly the syntax your project needs.

GitHub Flavored Markdown (GFM)

GitHub Flavored Markdown is the most widely used markdown dialect. It extends CommonMark with:
  • Autolink literals — bare URLs are turned into links automatically.
  • Footnotes[^1] style footnote references and definitions.
  • Strikethrough~~text~~ renders as <del>text</del>.
  • Tables — pipe-delimited table syntax.
  • Tasklists- [ ] and - [x] checkboxes in lists.
Install remark-gfm:
npm install remark-gfm
Then add it to your pipeline:
import {remark} from 'remark'
import remarkGfm from 'remark-gfm'

const file = await remark()
  .use(remarkGfm)
  .process('~~strikethrough~~ | table cell | [ ] task')

console.log(String(file))
remark-gfm registers both the micromark tokenizer extension and the mdast-util extension, so it works for both parsing and serializing GFM syntax.

YAML frontmatter

Many static site generators and content pipelines expect a YAML block at the top of a markdown file to carry metadata like title, date, or layout. The remark-frontmatter plugin adds support for parsing this block into the syntax tree as a dedicated yaml node. Install the plugin:
npm install remark-frontmatter
Add it to your pipeline:
import {unified} from 'unified'
import remarkParse from 'remark-parse'
import remarkFrontmatter from 'remark-frontmatter'
import remarkStringify from 'remark-stringify'

const file = await unified()
  .use(remarkParse)
  .use(remarkFrontmatter)
  .use(remarkStringify)
  .process(`---
title: Hello, world
---

# Intro
`)

console.log(String(file))
The frontmatter block is consumed by the plugin and exposed as a node in the mdast tree. When going to HTML via remark-rehype, it is excluded from the output by default — it does not appear as rendered content.

Other notable extensions

A rich ecosystem of syntax extension plugins exists beyond GFM and frontmatter. Here is a summary of the most commonly used ones:
PluginWhat it adds
remark-mathLaTeX math syntax — inline $...$ and block $$...$$
remark-mdxMDX support — JSX expressions and components inside markdown
remark-directiveGeneric directives proposal — :name[content]{attrs}
remark-footnotesFootnotes (also included in remark-gfm)
remark-breaksTreat single newlines as hard line breaks
Each of these follows the same usage pattern: install the package, then add it to your unified pipeline with .use().

How syntax extensions work under the hood

There is an important distinction between syntax extension plugins and transformer plugins. A transformer plugin (like remark-toc or remark-lint) receives the already-parsed mdast tree and modifies it. A syntax extension plugin (like remark-gfm or remark-math) teaches the parser itself to recognize new syntax, producing new node types in the tree before any transformer runs.If you add a syntax extension plugin after remark-stringify in the pipeline, the serializer will not know how to handle the new node types. Always place syntax plugins before any output plugin.
Syntax extension plugins work by registering extensions on the processor’s data store at configuration time. There are three hooks:
  • data('micromarkExtensions') — provides tokenizer-level extensions to micromark, the underlying markdown parser. This is what allows new syntax to be recognized at all.
  • data('fromMarkdownExtensions') — provides extensions to mdast-util-from-markdown, which converts micromark tokens into mdast nodes.
  • data('toMarkdownExtensions') — provides extensions to mdast-util-to-markdown, which serializes mdast nodes back to markdown text.
When you add remark-gfm to your pipeline, it populates all three of these data slots automatically — you do not need to interact with them directly unless you are building your own syntax extension from scratch.

Combining multiple extensions

Extensions compose cleanly. You can chain as many .use() calls as you need:
import {unified} from 'unified'
import remarkParse from 'remark-parse'
import remarkFrontmatter from 'remark-frontmatter'
import remarkGfm from 'remark-gfm'
import remarkMath from 'remark-math'
import rehypeKatex from 'rehype-katex'
import remarkRehype from 'remark-rehype'
import rehypeSanitize from 'rehype-sanitize'
import rehypeStringify from 'rehype-stringify'

const file = await unified()
  .use(remarkParse)
  .use(remarkFrontmatter)
  .use(remarkGfm)
  .use(remarkMath)
  .use(remarkRehype)
  .use(rehypeKatex)
  .use(rehypeSanitize)
  .use(rehypeStringify)
  .process(markdownSource)
The order matters: all remark plugins must come before remark-rehype, and all rehype plugins must come after it.

Next steps

Creating Plugins

Build your own remark plugin that transforms the mdast tree.

Markdown to HTML

Full walkthrough of converting markdown to sanitized HTML.

Build docs developers (and LLMs) love