mdast-util-mdx-jsx

Parses and serializes MDX JSX syntax within mdast syntax trees for markdown processing pipelines.

Library
npm
v3.2.0
32stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
31/100Needs Attention
Development Activity0
Maintenance32
Community20
Maturity60
Momentum12

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
70/100Good
Architecture80
Code Quality92
Innovation62
Learning Curve45

mdast-util-mdx-jsx is a pair of extensions that teach the mdast ecosystem how to read and write MDX JSX (<Component prop="x" />) inside markdown. mdxJsxFromMarkdown() plugs into mdast-util-from-markdown to turn JSX tokens produced by micromark-extension-mdx-jsx into mdxJsxFlowElement (block-level) and mdxJsxTextElement (inline) nodes, while mdxJsxToMarkdown() plugs into mdast-util-to-markdown to serialize those nodes back into markdown text, including attributes, expression values, and self-closing tags.

It is a low-level building block maintained by the syntax-tree/unified organization rather than something most developers install directly — it underlies higher-level packages like mdast-util-mdx and remark-mdx, which compose it with sibling extensions to give remark and unified pipelines full MDX support. Expression and spread attributes are parsed with acorn and exposed as ESTree Program nodes under data.estree, so tools built on top of it can statically inspect or transform JSX prop expressions rather than treating them as opaque strings.

What You Get

  • A mdxJsxFromMarkdown() extension that converts JSX tokens into mdxJsxFlowElement/mdxJsxTextElement mdast nodes
  • A mdxJsxToMarkdown() extension that serializes those nodes back to markdown text
  • ESTree-typed expression and spread attributes via data.estree, parsed with acorn
  • Configurable serialization: quote style, quote-smart selection, tight self-closing tags, and print-width-based attribute wrapping
  • Structured, position-aware parse errors (VFileMessage) for malformed JSX in markdown

Common Use Cases

  • Composing MDX support into a remark/unified pipeline alongside micromark-extension-mdx-jsx and mdast-util-mdx
  • Building static-site generators or doc tools that need to read or rewrite JSX embedded in markdown content
  • Writing linting or codemod tooling that visits mdxJsxFlowElement/mdxJsxTextElement nodes to validate JSX usage in MDX files
  • Implementing custom MDX compilers that need direct control over the JSX AST, separate from React/Babel’s JSX runtime

Under The Hood

Architecture The library is organized as two independent codecs assembled around mdast/unist token streams: lib/index.js exports mdxJsxFromMarkdown(), an extension object of enter/exit handler maps keyed by micromark token names (mirrored for mdxJsxFlowTag* and mdxJsxTextTag* variants) that build up a tag accumulator on the compile context’s data bag as the parser walks tokens, and mdxJsxToMarkdown(options), a handle map keyed by mdast node type that serializes back through internal containerFlow/inferDepth/createIndent helpers to respect indentation and print-width wrapping. There is no class hierarchy or dependency injection here — state flows entirely through the CompileContext/State objects handed in by mdast-util-from-markdown and mdast-util-to-markdown, so the package is purely a plugin/extension surface with no standalone entry point of its own; changing the shared tag shape or enter/exit key names would ripple into every sibling mdast-util-mdx-* package relying on the same token contract.

Tech Stack It’s pure ESM (Node 16+, single exports field), authored in typed JSDoc compiled to .d.ts declarations via tsc --build with type-coverage enforcing full type coverage, with runtime dependencies limited to mdast-util-from-markdown, mdast-util-to-markdown, devlop (assertions), ccount, parse-entities/stringify-entities (HTML entity handling), unist-util-stringify-position, and vfile-message for structured errors. Dev tooling adds micromark-extension-mdx-jsx/micromark-extension-mdx-md for parser-level fixtures, acorn for expression parsing in tests, xo plus prettier for linting/formatting, and c8 for coverage — a standard syntax-tree package in the unified/remark ecosystem with no runtime framework dependency beyond its sibling mdast-util packages.

Code Quality The test suite is a single large file run twice under different Node module conditions to exercise both development-only and production assertion paths, gated by a coverage threshold that requires full statement and branch coverage. Assertions rely on Node’s built-in assertion module rather than a separate test framework, keeping the dependency surface minimal. Error handling is explicit and typed: invalid syntax states throw structured, position-aware errors with stable error identifiers rather than silently coercing bad input, and internal invariant checks guard states that should be unreachable if the token stream is well-formed. Naming is consistent and verbose, mirroring token names one-to-one with handler function names, and the build pipeline chains type-checking, formatting, linting, and coverage into a single test script.

What Makes It Unique The library’s real contribution is a precise, reversible mapping between micromark’s low-level JSX tokens and mdast’s tree shape, correctly distinguishing block-level from inline JSX placement and serializing both back to markdown without losing fidelity — a round-trip guarantee most ad hoc JSX-in-markdown handling doesn’t attempt. It also exposes parsed expression attributes as real ESTree nodes so downstream tools can statically analyze JSX prop expressions instead of treating them as opaque strings. This isn’t novel in a research sense — it’s foundational infrastructure — but its round-trip rigor and estree bridging exceed typical regex-based JSX-in-markdown approaches.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search