When remark processes a markdown document, it does not manipulate raw strings — it first converts the source into a structured syntax tree, operates on that tree, and then serializes it back into output. The format of that tree is defined by mdast: the markdown abstract syntax tree specification.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.
What is mdast?
mdast is a specification maintained by the syntax-tree organization. It defines how every markdown construct — headings, paragraphs, lists, links, code blocks, emphasis, and more — is represented as a plain JSON object. Because the spec is language-agnostic, the same node shapes appear whether you are working in Node.js, Deno, or a browser. Every node in an mdast tree has at minimum atype field (a string identifying the node kind). Parent nodes also have a children array holding their descendant nodes. Leaf nodes carry a value string instead. Additional fields depend on the node type — for example, a heading node has a depth property (1–6), and a link node has url and title properties.
TypeScript types for the entire mdast specification are available in the @types/mdast package and are used throughout the remark ecosystem.
From markdown source to tree
The best way to understand mdast is to see a concrete example. Take this markdown fragment:remark-parse produces the following tree (positional info omitted for brevity):
## prefix becomes depth: 2 on the heading node. The *Pluto* emphasis creates a nested emphasis node whose single child is a text node. Plain text on either side of the emphasis becomes its own text nodes. The whole document would be wrapped in a root node with this heading as one of its children.
Key node types
The mdast specification defines node types for all standard markdown constructs:| Node type | Description | Key fields |
|---|---|---|
root | The top-level document node | children |
heading | ATX or setext heading (#, ##, …) | depth (1–6), children |
paragraph | A block of inline content | children |
text | Literal text within an inline context | value |
emphasis | Italic text (*…* or _…_) | children |
strong | Bold text (**…** or __…__) | children |
link | Inline or reference link | url, title, children |
image | Inline or reference image | url, title, alt |
list | Ordered or unordered list | ordered, start, spread, children |
listItem | A single item in a list | checked, spread, children |
code | Fenced or indented code block | lang, meta, value |
inlineCode | Backtick code span | value |
blockquote | Block-level quotation | children |
thematicBreak | A horizontal rule (---, ***, ___) | (none beyond type) |
html | Raw HTML fragment | value |
remark-gfm or remark-math) introduce additional node types on top of this base set.
Position information
Every node produced byremark-parse carries a position property that records exactly where in the source file the node starts and ends:
line— 1-based line number.column— 1-based column number (character position within the line).offset— 0-based character offset from the start of the file.
position because the node has no corresponding source location.
Some plugins deliberately strip position data to reduce output size. If your plugin depends on positions for error reporting, run it early in the pipeline before any stripping step.
Traversing and modifying the tree
The most common way to walk an mdast tree is with unist-util-visit, a utility that performs a depth-first traversal and calls your visitor function for every matching node type..use()), and it will receive the fully parsed tree before stringification:
children array is all it takes:
TypeScript and mdast types
The remark organization and the unified collective are fully typed with TypeScript. Import node types from@types/mdast to get accurate type-checking and autocomplete in your plugins:
import type statements keeps your plugin well-typed without adding a compile step to simple scripts.
Further reading
- mdast specification — the full node type reference, including all fields and their types.
- unist — the base specification that mdast extends; defines
Node,Parent,Literal, andposition. @types/mdast— TypeScript types for every mdast node.- unist-util-visit — depth-first tree traversal with typed visitor callbacks.