Skip to main content
The MarkdownParser class converts markdown text into a structured, fully-typed Abstract Syntax Tree (AST) following the CommonMark specification.

Installation

Install the markdown-parser package:
npm install markdown-parser

Creating a parser instance

Start by importing and instantiating the MarkdownParser class:
import { MarkdownParser } from "markdown-parser";

const parser = new MarkdownParser();
The parser instance maintains internal state for streaming operations. Create a new instance for each independent parsing session.

Parsing complete markdown

Use the parse() method to convert markdown text into an array of block nodes:
const nodes = parser.parse("# Hello World\nThis is a paragraph.");

console.log(nodes);
// [
//   { type: "heading", level: 1, children: [{ type: "text", text: "Hello World" }] },
//   { type: "paragraph", children: [{ type: "text", text: "This is a paragraph." }] }
// ]

Understanding the AST structure

The parser returns an array of BlockNode objects. Each node has a type property and type-specific fields:
const nodes = parser.parse("## Level 2 Heading");
// [{ type: "heading", level: 2, children: [...] }]

Working with inline nodes

Block nodes like paragraphs and headings contain inline nodes in their children array:
const markdown = "This is **bold** and *italic* text.";
const nodes = parser.parse(markdown);

const paragraph = nodes[0];
// {
//   type: "paragraph",
//   children: [
//     { type: "text", text: "This is " },
//     { type: "strong", children: [{ type: "text", text: "bold" }] },
//     { type: "text", text: " and " },
//     { type: "emphasis", children: [{ type: "text", text: "italic" }] },
//     { type: "text", text: " text." }
//   ]
// }

Parsing complex structures

The parser handles nested structures like blockquotes and lists:
1

Parse blockquotes

const markdown = "> This is a quote\n> with multiple lines";
const nodes = parser.parse(markdown);

// [{ type: "blockquote", children: [{ type: "paragraph", ... }] }]
2

Parse lists

const markdown = `
1. First item
2. Second item
   - Nested bullet
   - Another bullet
3. Third item
`;

const nodes = parser.parse(markdown);
// [{ type: "list", kind: "ordered", start: 1, items: [...] }]
3

Parse tables

const markdown = `
| Name | Age |
| ---- | --- |
| John | 30  |
| Jane | 25  |
`;

const nodes = parser.parse(markdown);
// [{ type: "table", head: {...}, body: {...}, alignments: [...] }]

Supported markdown features

The parser provides 100% CommonMark support plus GitHub Flavored Markdown (GFM) tables:

Block nodes

  • Heading (ATX and setext style)
  • Paragraph
  • Code block (fenced and indented)
  • Thematic break (horizontal rule)
  • HTML block
  • Blockquote
  • List (ordered and unordered)
  • Link reference definitions
  • Table (GFM)

Inline nodes

  • Text
  • Code span
  • Hard break
  • Soft break
  • HTML (inline)
  • Autolink
  • Link
  • Image
  • Emphasis
  • Strong

Type safety

The parser returns fully typed nodes, enabling excellent IDE autocomplete and type checking:
import { MarkdownParser, type BlockNode } from "markdown-parser";

const parser = new MarkdownParser();
const nodes: BlockNode[] = parser.parse("# Title");

// TypeScript knows the structure of each node type
for (const node of nodes) {
  if (node.type === "heading") {
    console.log(`Level ${node.level} heading`);
    // node.level is typed as 1 | 2 | 3 | 4 | 5 | 6
  }
}
Use TypeScript’s type narrowing with the type property to safely access type-specific fields on each node.

Error handling

The parser follows CommonMark’s error recovery principles - invalid markdown is handled gracefully:
// Malformed markdown is parsed as plain text
const nodes = parser.parse("####### Too many hashes");
// [{ type: "paragraph", children: [{ type: "text", text: "####### Too many hashes" }] }]

Next steps

Streaming mode

Parse markdown incrementally as it arrives from LLMs

React integration

Render parsed markdown in React applications

Build docs developers (and LLMs) love