This page documents @lanexio/parser-grammar-markdown, the Markdown grammar package implementing CommonMark 0.31.2 with GitHub Flavored Markdown (GFM) extensions: tables, task lists, strikethrough, autolinks, and more.
Version: Stable
Module name: parser-grammar-markdown
Package: @lanexio/parser-grammar-markdown
Import path: @lanexio/parser-grammar-markdown
Layer: 2 (Grammar)
Runtime: Universal (browser, server, edge worker)
Module format: ESM
Stability: Stable
Primary use case: Parse CommonMark and GFM Markdown documents into a flat AST.
Layer 2 dependency rules
This package depends only on Layer 1 core packages. It does not import from query, bridge, devtools, or entry packages. Grammar packs never depend on other grammar packs.
You need to parse Markdown documents (CommonMark or GFM) into a traversable AST.
You need to serialize a parsed Markdown tree back to Markdown source (roundtrip).
You want to extract text content or render Markdown to HTML.
Boundary Description Inputs Uint8Array (source bytes) + optional ParseMarkdownOptionsOutputs LexTree (flat AST rooted at MdKind.Document)Side effects Side-effect import ./embed.js registers fenced-code-block embeddings for CSS, JSON, HTML guest languages Determinism Yes (same bytes + same options produce identical tree) External dependencies @lanexio/parser-coreNever-throw guarantee Yes for all parse entry points Security surface Serializer output emits raw Markdown source. renderMarkdownHtml emits raw HTML.
Install the package.
pnpm add @lanexio/parser-grammar-markdown
npm install @lanexio/parser-grammar-markdown
yarn add @lanexio/parser-grammar-markdown
Import the named export.
import { parseMarkdown } from ' @lanexio/parser-grammar-markdown ' ;
Requirement Required Layer Notes @lanexio/parser-coreYes 1 ^1.0.0
import { parseMarkdown } from ' @lanexio/parser-grammar-markdown ' ;
const encoder = new TextEncoder ();
const bytes = encoder . encode ( ' # Hello \n\n A paragraph with **bold** text. ' );
const tree = parseMarkdown (bytes);
console . log (tree . nodeCount ); // total nodes in the flat AST
console . log (tree . root . kind ); // MdKind.Document
import { parseMarkdown } from ' @lanexio/parser-grammar-markdown ' ;
const encoder = new TextEncoder ();
const tree = parseMarkdown (
encoder . encode ( ' # CommonMark only ' ) ,
import { parseMarkdown, serializeMarkdown } from ' @lanexio/parser-grammar-markdown ' ;
const encoder = new TextEncoder ();
const tree = parseMarkdown (encoder . encode ( ' # Hello \n\n A paragraph. ' ));
const markdown = serializeMarkdown (tree);
// "# Hello\n\nA paragraph.\n"
Export Type Description parseMarkdown(source: Uint8Array, options?: ParseMarkdownOptions) => LexTreeParse Markdown. Never throws. parseMarkdownWithScan(source: Uint8Array, options?: ParseMarkdownOptions) => Promise<LexTree>Parse Markdown with pre-computed structural scan. Async. serializeMarkdown(input: LexTree | LexNode) => stringSerialize tree back to Markdown source (roundtrip). renderMarkdownHtml(tree: LexTree, options?: RenderMarkdownHtmlOptions) => stringRender Markdown tree to HTML string. textContent(node: LexNode) => stringExtract plain text from a Markdown tree. MdKindconst objectNumeric kind IDs for all Markdown node types. MdFieldconst objectNumeric field IDs for Markdown element slots. MD_FIELD_NAMES_BY_IDreadonly string[]Field name lookup by numeric field ID. MdParseErrorCodeconst objectParse error code constants. MD_FLAG_HEADING_LEVEL_MASKnumberBitmask for heading level in node flags. MD_FLAG_HEADING_LEVEL_SHIFTnumberBit shift for heading level in node flags. MD_FLAG_LIST_LOOSEnumberFlag for loose list items. mdEncodeHeadingLevel(level: number) => numberEncode heading level into node flags. mdHeadingLevel(flags: number) => numberDecode heading level from node flags. mdListIsLoose(flags: number) => booleanCheck if a list node is loose. markdownGrammarLanexioParserPureGrammarGrammar descriptor for use with parser-pure. markdownRegistrationGrammarRegistrationRegistration for the unified grammar registry.
Field Type Required Default Description gfmbooleanNo trueEnable GFM extensions (tables, task lists, strikethrough, autolinks). extendedAutolinkbooleanNo true (when gfm: true)Enable GFM extended autolink detection (bare URLs, www . hosts, email). useSimdScanbooleanNo falseUse SIMD or scalar pre-scan for delimiter bytes during inline parsing.
Field Type Required Default Description (reserved) - - - Reserved for future extension.
Property Type Description rootLexNodeRoot node (MdKind.Document). nodeCountnumberTotal nodes in the tree. sourceUint8ArrayOriginal parsed bytes.
Type Purpose Notes ParseMarkdownOptionsOptions for parseMarkdown See options table above. RenderMarkdownHtmlOptionsOptions for renderMarkdownHtml Reserved for future extension. MdParseErrorParse error descriptor Returned via error codes.
GFM extensions are enabled by default. This includes tables, task list items, strikethrough, autolinks, and extended autolinks. Pass { gfm: false } to restrict to strict CommonMark 0.31.2 only.
Side-effect import ./embed.js registers known guest languages (CSS, JSON, HTML) for fenced code block embedding. When a fenced code block has an info string matching a registered language, the block content can be parsed as the guest language.
The Markdown parser preserves the document outline (headings, lists) in the AST structure. Serialization output preserves semantic Markdown syntax. renderMarkdownHtml produces HTML that preserves semantic structure.
Concern Status Generated output semantics Preserves document structure (headings, lists, emphasis) ARIA attributes in serialized output Not applicable (Markdown source output) Semantic element round-trip Yes (parse.serialize.parse is structurally identical)
parseMarkdown never throws on any byte sequence.
renderMarkdownHtml emits raw HTML — callers must sanitize before browser insertion.
serializeMarkdown emits raw Markdown source, not HTML.
Threat Mitigation Status Malformed input byte sequence Panic-free guarantee: all inputs accepted, errors produce LexError AST nodes Implemented XSS via HTML renderer output renderMarkdownHtml emits raw HTML — caller is responsible for safe insertionDocumented
Package Relationship Layer Notes @lanexio/parser-coreRequires 1 Provides LexTree, LexNode, LexCursor @lanexio/parser-grammar-htmlDev dependency 2 Used for HTML embedding in fenced code blocks @lanexio/parser-pureConsumes 4 Wraps parseMarkdown in a unified bridge
import { parseMarkdown, MdKind } from ' @lanexio/parser-grammar-markdown ' ;
import { LexQuery } from ' @lanexio/parser-query ' ;
const encoder = new TextEncoder ();
const tree = parseMarkdown (encoder . encode ( ' # Title \n\n A paragraph. \n\n - item one \n - item two ' ));
const resolver = ( name : string ) => (MdKind as Record < string , number | undefined > )[name];
const query = LexQuery . compile ( ' Item ' , resolver);
for ( const node of query . matches (tree)) {
console . log (node . kind , node . range );
Version Date Status Notable changes 1.0.02026-05-29Current Initial stable release. Apache-2.0.
Parsing Markdown Guide: parse Markdown with options, serialization, kind constants. Flat AST How the 16-byte node layout works and how to traverse it efficiently.