remark-parse vs remark-gfm vs remark-mdx vs remark-frontmatter vs remark-html
Extending Markdown Processing in the Unified Ecosystem
remark-parseremark-gfmremark-mdxremark-frontmatterremark-htmlSimilar Packages:
Extending Markdown Processing in the Unified Ecosystem

remark-frontmatter, remark-gfm, remark-html, remark-mdx, and remark-parse are plugins or core components in the Unified ecosystem (specifically Remark) that enable advanced Markdown processing. remark-parse is the foundational parser that converts Markdown strings into an abstract syntax tree (AST). The other packages are plugins that extend this AST: remark-frontmatter handles YAML/TOML frontmatter, remark-gfm adds GitHub Flavored Markdown support (tables, task lists, etc.), remark-html transforms the AST into HTML strings, and remark-mdx enables parsing and processing of MDX (Markdown + JSX). Together, they allow developers to build customizable, powerful Markdown-to-HTML pipelines with support for metadata, extended syntax, and embedded components.

Npm Package Weekly Downloads Trend
3 Years
Github Stars Ranking
Stat Detail
Package
Downloads
Stars
Size
Issues
Publish
License
remark-parse19,297,9098,72519.5 kB52 years agoMIT
remark-gfm11,814,8841,14422 kB2a year agoMIT
remark-mdx4,568,05919,22614.7 kB205 months agoMIT
remark-frontmatter2,123,02731621.2 kB02 years agoMIT
remark-html459,16533917 kB02 years agoMIT

Processing Markdown with Remark: Parsing, Extending, and Serializing

When building modern content pipelines — whether for blogs, documentation, or CMS backends — developers often reach for the Unified ecosystem, where Remark handles Markdown processing. The packages remark-parse, remark-frontmatter, remark-gfm, remark-mdx, and remark-html each play distinct roles in this pipeline. Understanding how they fit together — and when to use which — is key to building efficient, maintainable systems.

🧱 Core Roles: Parser, Transformers, and Serializer

Every Remark pipeline follows a simple flow:

  1. Parse Markdown text into an AST (remark-parse)
  2. Transform the AST with plugins (e.g., remark-gfm, remark-frontmatter, remark-mdx)
  3. Serialize the AST into output (e.g., remark-html for HTML strings)

Let’s see how each package fits into this flow.

remark-parse: The Foundation

This is the only parser in the list. Without it, you can’t process Markdown at all in a Remark pipeline. It converts a string like # Hello into a structured tree that other tools can modify.

import { unified } from 'unified';
import remarkParse from 'remark-parse';

const processor = unified().use(remarkParse);
const ast = processor.parse('# Hello');
// Returns a root node with a heading child

⚠️ You must use remark-parse (or a compatible parser) before applying any Remark plugins. None of the other packages in this comparison can parse raw Markdown on their own.

remark-html: The Output Generator

Once you have an AST, remark-html turns it into a plain HTML string. It’s a compiler, not a transformer — it doesn’t modify the AST; it consumes it.

import { unified } from 'unified';
import remarkParse from 'remark-parse';
import remarkHtml from 'remark-html';

const processor = unified()
  .use(remarkParse)
  .use(remarkHtml);

const html = processor.processSync('# Hello').toString();
// Returns '<h1>Hello</h1>'

Note: remark-html works after all transformations. If you’ve added GFM tables or MDX components, remark-html won’t know how to render them unless you’ve first converted those nodes to standard HTML-compatible ones (usually via remark-rehype). But for basic Markdown, it’s sufficient.

remark-frontmatter, remark-gfm, remark-mdx: AST Transformers

These three modify the AST during processing. They must come after remark-parse and before serialization.

remark-frontmatter: Extracting Metadata

Handles frontmatter blocks like:

---
title: My Post
date: 2024-01-01
---

# Content

Usage:

import remarkFrontmatter from 'remark-frontmatter';

const processor = unified()
  .use(remarkParse)
  .use(remarkFrontmatter, ['yaml', 'toml']); // supports multiple formats

const ast = processor.parse('---\ntitle: Test\n---\n# Hi');
// AST now includes a `yaml` node at the top

Without this plugin, the --- block would be parsed as a thematic break (horizontal rule), corrupting your metadata.

remark-gfm: Adding GitHub Flavored Markdown

Enables syntax like tables, task lists, and autolinks:

| Name | Age |
|------|-----|
| Alice| 30  |

- [x] Done
- [ ] Todo

Visit https://example.com

Usage:

import remarkGfm from 'remark-gfm';

const processor = unified()
  .use(remarkParse)
  .use(remarkGfm);

const ast = processor.parse('| A | B |\n|---|---|\n| 1 | 2 |');
// AST includes a `table` node

Without remark-gfm, that table would be parsed as plain paragraphs.

remark-mdx: Embedding JSX in Markdown

Allows mixing React-like components in Markdown:

# Hello

Here is a chart:

<BarChart data={data} />

Usage:

import remarkMdx from 'remark-mdx';

const processor = unified()
  .use(remarkParse)
  .use(remarkMdx);

const ast = processor.parse('# Hi\n\n<MyComponent />');
// AST includes an `mdxJsxTextElement` node

🔒 Warning: MDX execution can introduce security risks (e.g., arbitrary code injection) if used with untrusted input. Always sanitize or restrict component usage in public-facing apps.

🔄 Pipeline Order Matters

The sequence of plugins affects correctness. Here’s a typical full pipeline for GFM + frontmatter:

import { unified } from 'unified';
import remarkParse from 'remark-parse';
import remarkFrontmatter from 'remark-frontmatter';
import remarkGfm from 'remark-gfm';
import remarkHtml from 'remark-html';

const processor = unified()
  .use(remarkParse)
  .use(remarkFrontmatter, ['yaml'])
  .use(remarkGfm)
  .use(remarkHtml);

const result = processor.processSync(`---
title: Demo
---

- [x] Task

| A | B |
|---|---|`);

If you put remark-html before remark-gfm, tables won’t render — because the HTML compiler runs before the GFM syntax is recognized.

🛑 What These Packages Don’t Do

  • None of them handle HTML sanitization — if you output HTML from user content, use rehype-sanitize.
  • remark-mdx does not execute JSX — it only parses it into an AST. To render components, you need additional tooling (e.g., @mdx-js/react).
  • remark-html cannot render MDX components — it outputs literal <MyComponent /> as a string. For component-aware rendering, convert to React via remark-rehype + rehype-react.

🧩 When to Combine vs. Use Alone

Use CaseRequired Packages
Basic Markdown → HTMLremark-parse + remark-html
Markdown with YAML metadataAdd remark-frontmatter
GitHub-style MarkdownAdd remark-gfm
Interactive docs with componentsReplace remark-html with MDX-aware pipeline (remark-mdxremark-rehyperehype-react)

💡 Practical Recommendation

Start minimal: always begin with remark-parse and remark-html. Then layer in transformers only as needed:

  • Need metadata? → add remark-frontmatter
  • Accepting GitHub-style input? → add remark-gfm
  • Building a React-based docs site? → replace remark-html with an MDX pipeline using remark-mdx

Avoid over-engineering. If you don’t use tables or task lists, skip remark-gfm. If you don’t have frontmatter, skip remark-frontmatter. Each plugin adds maintenance surface and potential edge cases.

By understanding these roles — parser, transformers, serializer — you’ll build cleaner, more predictable Markdown processing systems.

How to Choose: remark-parse vs remark-gfm vs remark-mdx vs remark-frontmatter vs remark-html
  • remark-parse:

    Choose remark-parse whenever you start processing Markdown in a Unified pipeline — it’s the required first step to turn raw Markdown text into a syntax tree that other plugins can transform. Never skip it unless you’re working directly with an existing AST. It’s lightweight and focused solely on parsing, so always include it in any Remark-based workflow.

  • remark-gfm:

    Choose remark-gfm when you need to support GitHub-style Markdown features such as tables, strikethrough, task lists, or autolinks. This is essential for user-generated content from GitHub or tools that expect GFM compatibility. Don’t use it if you only need standard CommonMark compliance, as it introduces extra syntax rules that may not be needed.

  • remark-mdx:

    Choose remark-mdx when you need to process MDX — Markdown that supports embedded JSX components. This is critical for documentation sites, interactive blogs, or design systems built with frameworks like Next.js or Gatsby. Only use it if you actually require component interpolation; otherwise, stick with standard Markdown plugins to avoid complexity and security considerations.

  • remark-frontmatter:

    Choose remark-frontmatter when your Markdown files include metadata blocks (like YAML or TOML) at the top — common in static site generators like Jekyll or Hugo. It safely extracts this data into the AST without affecting the rest of the document. Avoid it if your content doesn’t use frontmatter, as it adds unnecessary parsing overhead.

  • remark-html:

    Choose remark-html when your goal is to convert a Markdown AST into a plain HTML string for rendering in browsers or email templates. It’s the standard serializer after parsing and transforming Markdown. Avoid using it if you’re targeting React (use rehype-react instead) or another output format like JSON or PDF.

README for remark-parse

remark-parse

Build Coverage Downloads Size Sponsors Backers Chat

remark plugin to add support for parsing from markdown.

Contents

What is this?

This package is a unified (remark) plugin that defines how to take markdown as input and turn it into a syntax tree.

See the monorepo readme for info on what the remark ecosystem is.

When should I use this?

This plugin adds support to unified for parsing markdown. If you also need to serialize markdown, you can alternatively use remark, which combines unified, this plugin, and remark-stringify.

If you just want to turn markdown into HTML (with maybe a few extensions), we recommend micromark instead. If you don’t use plugins and want to access the syntax tree, you can directly use mdast-util-from-markdown. remark focusses on making it easier to transform content by abstracting these internals away.

You can combine this plugin with other plugins to add syntax extensions. Notable examples that deeply integrate with it are remark-gfm, remark-mdx, remark-frontmatter, remark-math, and remark-directive. You can also use any other remark plugin after remark-parse.

Install

This package is ESM only. In Node.js (version 16+), install with npm:

npm install remark-parse

In Deno with esm.sh:

import remarkParse from 'https://esm.sh/remark-parse@11'

In browsers with esm.sh:

<script type="module">
  import remarkParse from 'https://esm.sh/remark-parse@11?bundle'
</script>

Use

Say we have the following module example.js:

import rehypeStringify from 'rehype-stringify'
import remarkGfm from 'remark-gfm'
import remarkParse from 'remark-parse'
import remarkRehype from 'remark-rehype'
import {unified} from 'unified'

const doc = `
# Mercury

**Mercury** is the first planet from the [Sun](https://en.wikipedia.org/wiki/Sun)
and the smallest planet in the Solar System.
`

const file = await unified()
  .use(remarkParse)
  .use(remarkGfm)
  .use(remarkRehype)
  .use(rehypeStringify)
  .process(doc)

console.log(String(file))

…then running node example.js yields:

<h1>Mercury</h1>
<p><strong>Mercury</strong> is the first planet from the <a href="https://en.wikipedia.org/wiki/Sun">Sun</a>
and the smallest planet in the Solar System.</p>

API

This package exports no identifiers. The default export is remarkParse.

unified().use(remarkParse)

Add support for parsing from markdown.

Parameters

There are no parameters.

Returns

Nothing (undefined).

Examples

Example: support GFM and frontmatter

We support CommonMark by default. Non-standard markdown extensions can be enabled with plugins.

This example shows how to support GFM features (autolink literals, footnotes, strikethrough, tables, tasklists) and frontmatter (YAML):

import rehypeStringify from 'rehype-stringify'
import remarkFrontmatter from 'remark-frontmatter'
import remarkGfm from 'remark-gfm'
import remarkParse from 'remark-parse'
import remarkRehype from 'remark-rehype'
import {unified} from 'unified'

const doc = `---
layout: solar-system
---

# Hi ~~Mars~~Venus!
`

const file = await unified()
  .use(remarkParse)
  .use(remarkFrontmatter)
  .use(remarkGfm)
  .use(remarkRehype)
  .use(rehypeStringify)
  .process(doc)

console.log(String(file))

Yields:

<h1>Hi <del>Mars</del>Venus!</h1>

Example: turning markdown into a man page

Man pages (short for manual pages) are a way to document CLIs (example: type man git-log in your terminal). They use an old markup format called roff. There’s a remark plugin, remark-man, that can serialize as roff.

This example shows how to turn markdown into man pages by using unified with remark-parse and remark-man:

import remarkMan from 'remark-man'
import remarkParse from 'remark-parse'
import {unified} from 'unified'

const doc = `
# titan(7) -- largest moon of saturn

Titan is the largest moon…
`

const file = await unified().use(remarkParse).use(remarkMan).process(doc)

console.log(String(file))

Yields:

.TH "TITAN" "7" "September 2023" "" ""
.SH "NAME"
\fBtitan\fR - largest moon of saturn
.P
Titan is the largest moon…

Syntax

Markdown is parsed according to CommonMark. Other plugins can add support for syntax extensions. If you’re interested in extending markdown, more information is available in micromark’s readme.

Syntax tree

The syntax tree used in remark is mdast.

Types

This package is fully typed with TypeScript. It exports the additional type Options (which is currently empty).

Compatibility

Projects maintained by the unified collective are compatible with maintained versions of Node.js.

When we cut a new major release, we drop support for unmaintained versions of Node. This means we try to keep the current release line, remark-parse@^11, compatible with Node.js 16.

Security

As markdown can be turned into HTML and improper use of HTML can open you up to cross-site scripting (XSS) attacks, use of remark can be unsafe. When going to HTML, you will combine remark with rehype, in which case you should use rehype-sanitize.

Use of remark plugins could also open you up to other attacks. Carefully assess each plugin and the risks involved in using them.

For info on how to submit a report, see our security policy.

Contribute

See contributing.md in remarkjs/.github for ways to get started. See support.md for ways to get help. Join us in Discussions to chat with the community and contributors.

This project has a code of conduct. By interacting with this repository, organization, or community you agree to abide by its terms.

Sponsor

Support this effort and give back by sponsoring on OpenCollective!

Vercel

Motif

HashiCorp

GitBook

Gatsby

Netlify

Coinbase

ThemeIsle

Expo

Boost Note

Markdown Space

Holloway


You?

License

MIT © Titus Wormer