npm.io
3.1.1 • Published 10 months ago

@mdx-js/mdx

Licence
MIT
Version
3.1.1
Deps
25
Size
160 kB
Vulns
0
Weekly
0
Stars
19.7K

@mdx-js/mdx

Build Coverage Downloads Size Sponsors Backers Chat

MDX compiler.

Contents

What is this?

This package is a compiler that turns MDX into JavaScript. It can also evaluate MDX code.

When should I use this?

This is the core compiler for turning MDX into JavaScript which gives you the most control. If you’re using a bundler (Rollup, esbuild, webpack), a site builder (Next.js), or build system (Vite) which comes with a bundler, you’re better off using an integration: see § Integrations.

Install

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

npm install @mdx-js/mdx

In Deno with esm.sh:

import {compile} from 'https://esm.sh/@mdx-js/mdx@3'

In browsers with esm.sh:

<script type="module">
  import {compile} from 'https://esm.sh/@mdx-js/mdx@3?bundle'
</script>

Use

Say we have an MDX document, example.mdx:

export function Thing() {
  return <>World!</>
}

# Hello, <Thing />

…and some code in example.js to compile example.mdx to JavaScript:

import fs from 'node:fs/promises'
import {compile} from '@mdx-js/mdx'

const compiled = await compile(await fs.readFile('example.mdx'))

console.log(String(compiled))

Yields roughly:

import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs} from 'react/jsx-runtime'

export function Thing() {
  return _jsx(_Fragment, {children: 'World!'})
}

function _createMdxContent(props) {
  const _components = {h1: 'h1', ...props.components}
  return _jsxs(_components.h1, {children: ['Hello, ', _jsx(Thing, {})]})
}

export default function MDXContent(props = {}) {
  const {wrapper: MDXLayout} = props.components || {}
  return MDXLayout
    ? _jsx(MDXLayout, {...props, children: _jsx(_createMdxContent, {...props})})
    : _createMdxContent(props)
}

See § Using MDX for more on how MDX work and how to use the result.

API

This package exports the following identifiers: compile, compileSync, createProcessor, evaluate, evaluateSync, nodeTypes, run, and runSync. There is no default export.

compile(file, options?)

Compile MDX to JS.

Parameters
Returns

Promise to compiled file (Promise<VFile>).

Examples

The input value for file can be many different things. You can pass a string, Uint8Array in UTF-8, VFile, or anything that can be given to new VFile.

import {compile} from '@mdx-js/mdx'
import {VFile} from 'vfile'

await compile(':)')
await compile(Buffer.from(':-)'))
await compile({path: 'path/to/file.mdx', value: '🥳'})
await compile(new VFile({path: 'path/to/file.mdx', value: '🤭'}))

The output VFile can be used to access more than the generated code:

import {compile} from '@mdx-js/mdx'
import remarkPresetLintConsistent from 'remark-preset-lint-consistent' // Lint rules to check for consistent markdown.
import {reporter} from 'vfile-reporter'

const file = await compile('*like this* or _like this_?', {remarkPlugins: [remarkPresetLintConsistent]})

console.error(reporter(file))

Yields:

  1:16-1:27  warning  Emphasis should use `*` as a marker  emphasis-marker  remark-lint

⚠ 1 warning
compileSync(file, options?)

Synchronously compile MDX to JS.

When possible please use the async compile.

Parameters
Returns

Compiled file (VFile).

createProcessor(options?)

Create a processor to compile markdown or MDX to JavaScript.

Note: format: 'detect' is not allowed in ProcessorOptions.

Parameters
Returns

Processor (Processor from unified).

evaluate(file, options)

Compile and run MDX.

When you trust your content, evaluate can work. When possible, use compile, write to a file, and then run with Node or use one of the § Integrations.

Danger: it’s called evaluate because it evals JavaScript.

Parameters
Returns

Promise to a module (Promise<MDXModule> from mdx/types.js).

The result is an object with a default field set to the component; anything else that was exported is available too. For example, assuming the contents of example.mdx from § Use was in file, then:

import {evaluate} from '@mdx-js/mdx'
import * as runtime from 'react/jsx-runtime'

console.log(await evaluate(file, runtime))

…yields:

{Thing: [Function: Thing], default: [Function: MDXContent]}
Notes

Compiling (and running) MDX takes time.

If you are live-rendering a string of MDX that often changes using a virtual DOM based framework (such as React), one performance improvement is to call the MDXContent component yourself. The reason is that the evaluate creates a new function each time, which cannot be diffed:

 const {default: MDXContent} = await evaluate('…')

-<MDXContent {...props} />
+MDXContent(props)
evaluateSync(file, options)

Compile and run MDX, synchronously.

When possible please use the async evaluate.

Danger: it’s called evaluate because it evals JavaScript.

Parameters
Returns

Module (MDXModule from mdx/types.js).

nodeTypes

List of node types made by mdast-util-mdx, which have to be passed through untouched from the mdast tree to the hast tree (Array<string>).

run(code, options)

Run code compiled with outputFormat: 'function-body'.

Danger: this evals JavaScript.

Parameters
  • code (VFile or string) — JavaScript function body to run
  • options (RunOptions, required) — configuration
Returns

Promise to a module (Promise<MDXModule> from mdx/types.js); the result is an object with a default field set to the component; anything else that was exported is available too.

Example

On the server:

import {compile} from '@mdx-js/mdx'

const code = String(await compile('# hi', {outputFormat: 'function-body'}))
// To do: send `code` to the client somehow.

On the client:

import {run} from '@mdx-js/mdx'
import * as runtime from 'react/jsx-runtime'

const code = '' // To do: get `code` from server somehow.

const {default: Content} = await run(code, {...runtime, baseUrl: import.meta.url})

console.log(Content)

…yields:

[Function: MDXContent]
runSync(code, options)

Run code, synchronously.

When possible please use the async run.

Danger: this evals JavaScript.

Parameters
  • code (VFile or string) — JavaScript function body to run
  • options (RunOptions, required) — configuration
Returns

Module (MDXModule from mdx/types.js).

CompileOptions

Configuration for compile (TypeScript type).

CompileOptions is the same as ProcessorOptions with the exception that the format option supports a 'detect' value, which is the default. The 'detect' format means to use 'md' for files with an extension in mdExtensions and 'mdx' otherwise.

Type
/**
 * Configuration for `compile`
 */
type CompileOptions = Omit<ProcessorOptions, 'format'> & {
  /**
   * Format of `file` (default: `'detect'`).
   */
  format?: 'detect' | 'md' | 'mdx' | null | undefined
}
EvaluateOptions

Configuration for evaluate (TypeScript type).

EvaluateOptions is the same as CompileOptions, except that the options baseUrl, jsx, jsxImportSource, jsxRuntime, outputFormat, pragma, pragmaFrag, pragmaImportSource, and providerImportSource are not allowed, and that RunOptions are also used.

Type
/**
 * Configuration for `evaluate`.
 */
type EvaluateOptions = Omit<
  CompileOptions,
  | 'baseUrl' // Note that this is also in `RunOptions`.
  | 'jsx'
  | 'jsxImportSource'
  | 'jsxRuntime'
  | 'outputFormat'
  | 'pragma'
  | 'pragmaFrag'
  | 'pragmaImportSource'
  | 'providerImportSource'
> &
  RunOptions
Fragment

Represent the children, typically a symbol (TypeScript type).

Type
type Fragment = unknown
Jsx

Create a production element (TypeScript type).

Parameters
  • type (unknown) — element type: Fragment symbol, tag name (string), component
  • properties (Properties) — element properties and children
  • key (string or undefined) — key to use
Returns

Element from your framework (JSX.Element).

JsxDev

Create a development element (TypeScript type).

Parameters
  • type (unknown) — element type: Fragment symbol, tag name (string), component
  • properties (Properties) — element properties and children
  • key (string or undefined) — key to use
  • isStaticChildren (boolean) — whether two or more children are passed (in an array), which is whether jsxs or jsx would be used
  • source (Source) — info about source
  • self (unknown) — context object (this)
ProcessorOptions

Configuration for createProcessor (TypeScript type).

Fields
  • SourceMapGenerator (SourceMapGenerator from source-map, optional) — add a source map (object form) as the map field on the resulting file

    Expand example

    Assuming example.mdx from § Use exists, then:

    import fs from 'node:fs/promises'
    import {compile} from '@mdx-js/mdx'
    import {SourceMapGenerator} from 'source-map'
    
    const file = await compile(
      {path: 'example.mdx', value: await fs.readFile('example.mdx')},
      {SourceMapGenerator}
    )
    
    console.log(file.map)

    …yields:

    {
      file: 'example.mdx',
      mappings: ';;aAAaA,QAAQ;YAAQ;;;;;;;;iBAE3B',
      names: ['Thing'],
      sources: ['example.mdx'],
      version: 3
    }
  • baseUrl (URL or string, optional, example: import.meta.url) — use this URL as import.meta.url and resolve import and export … from relative to it

    Expand example

    Say we have a module example.js:

    import {compile} from '@mdx-js/mdx'
    
    const code = 'export {number} from "./data.js"\n\n# hi'
    const baseUrl = 'https://a.full/url' // Typically `import.meta.url`
    
    console.log(String(await compile(code, {baseUrl})))

    …now running node example.js yields:

    import {jsx as _jsx} from 'react/jsx-runtime'
    export {number} from 'https://a.full/data.js'
    function _createMdxContent(props) { /* … */ }
    export default function MDXContent(props = {}) { /* … */ }
  • development (boolean, default: false) — whether to add extra info to error messages in generated code and use the development automatic JSX runtime (Fragment and jsxDEV from /jsx-dev-runtime); when using the webpack loader (@mdx-js/loader) or the Rollup integration (@mdx-js/rollup) through Vite, this is automatically inferred from how you configure those tools

    Expand example

    Say we had some MDX that references a component that can be passed or provided at runtime:

    **Note**<NoteIcon />: some stuff.

    And a module to evaluate that:

    import fs from 'node:fs/promises'
    import {evaluate} from '@mdx-js/mdx'
    import * as runtime from 'react/jsx-runtime'
    
    const path = 'example.mdx'
    const value = await fs.readFile(path)
    const MDXContent = (await evaluate({path, value}, {...runtime, baseUrl: import.meta.url})).default
    
    console.log(MDXContent({}))

    …running that would normally (production) yield:

    Error: Expected component `NoteIcon` to be defined: you likely forgot to import, pass, or provide it.
        at _missingMdxReference (eval at run (…/@mdx-js/mdx/lib/run.js:18:10), <anonymous>:27:9)
        at _createMdxContent (eval at run (…/@mdx-js/mdx/lib/run.js:18:10), <anonymous>:15:20)
        at MDXContent (eval at run (…/@mdx-js/mdx/lib/run.js:18:10), <anonymous>:9:9)
        at main (…/example.js:11:15)

    …but if we add development: true to our example:

    @@ -7,6 +7,6 @@
    import fs from 'node:fs/promises'
    -import * as runtime from 'react/jsx-runtime'
    +import * as runtime from 'react/jsx-dev-runtime'
    import {evaluate} from '@mdx-js/mdx'
    
    const path = 'example.mdx'
    const value = await fs.readFile(path)
    -const MDXContent = (await evaluate({path, value}, {...runtime, baseUrl: import.meta.url})).default
    +const MDXContent = (await evaluate({path, value}, {development: true, ...runtime, baseUrl: import.meta.url})).default
    
    console.log(MDXContent({}))

    …and we’d run it again, we’d get:

    Error: Expected component `NoteIcon` to be defined: you likely forgot to import, pass, or provide it.
    It’s referenced in your code at `1:9-1:21` in `example.mdx`
    provide it.
        at _missingMdxReference (eval at run (…/@mdx-js/mdx/lib/run.js:18:10), <anonymous>:27:9)
        at _createMdxContent (eval at run (…/@mdx-js/mdx/lib/run.js:18:10), <anonymous>:15:20)
        at MDXContent (eval at run (…/@mdx-js/mdx/lib/run.js:18:10), <anonymous>:9:9)
        at main (…/example.js:11:15)
  • elementAttributeNameCase ('html' or 'react, default: 'react') — casing to use for attribute names; HTML casing is for example class, stroke-linecap, xml:lang; React casing is for example className, strokeLinecap, xmlLang; for JSX components written in MDX, the author has to be aware of which framework they use and write code accordingly; for AST nodes generated by this project, this option configures it

  • format ('md' or 'mdx', default: 'mdx') — format of the file; 'md' means treat as markdown and 'mdx' means treat as MDX

    Expand example
    compile('…') // Seen as MDX.
    compile('…', {format: 'mdx'}) // Seen as MDX.
    compile('…', {format: 'md'}) // Seen as markdown.
  • jsx (boolean, default: false) — whether to keep JSX; the default is to compile JSX away so that the resulting file is immediately runnable.

    Expand example

    If file is the contents of example.mdx from § Use, then:

    compile(file, {jsx: true})

    …yields this difference:

    -import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs} from 'react/jsx-runtime'
    +/*@jsxRuntime automatic*/
    +/*@jsxImportSource react*/
    
    export function Thing() {
    -  return _jsx(_Fragment, {children: 'World'})
    +  return <>World!</>
    }
    
    function _createMdxContent(props) {
      const _components = {
        h1: 'h1',
        ...props.components
      }
    -  return _jsxs(_components.h1, {children: ['Hello ', _jsx(Thing, {})]})
    +  return <_components.h1>{"Hello "}<Thing /></_components.h1>
    }
    
    export default function MDXContent(props = {}) {
      const {wrapper: MDXLayout} = props.components || {}
      return MDXLayout
    -    ? _jsx(MDXLayout, {
    -        ...props,
    -        children: _jsx(_createMdxContent, props)
    -      })
    +    ? <MDXLayout {...props}><_createMdxContent {...props} /></MDXLayout>
        : _createMdxContent(props)
    }
    }
  • jsxImportSource (string, default: 'react') — place to import automatic JSX runtimes from; when in the automatic runtime, this is used to define an import for Fragment, jsx, jsxDEV, and jsxs

    Expand example

    If file is the contents of example.mdx from § Use, then:

    compile(file, {jsxImportSource: 'preact'})

    …yields this difference:

    -import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs} from 'react/jsx-runtime'
    +import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from 'preact/jsx-runtime'
  • jsxRuntime ('automatic' or 'classic', default: 'automatic') — JSX runtime to use; the automatic runtime compiles to import _jsx from '$importSource/jsx-runtime'\n_jsx('p'); the classic runtime compiles to calls such as h('p')

    Note: support for the classic runtime is deprecated and will likely be removed in the next major version.

    Expand example

    If file is the contents of example.mdx from § Use, then:

    compile(file, {jsxRuntime: 'classic'})

    …yields this difference:

    -import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs} from 'react/jsx-runtime'
    +import React from 'react'
    
    export function Thing() {
    -  return _jsx(_Fragment, {children: 'World'})
    +  return React.createElement(React.Fragment, null, 'World!')
    }
    …
  • outputFormat ('function-body' or 'program', default: 'program') — output format to generate; in most cases 'program' should be used, it results in a whole program; internally evaluate uses 'function-body' to compile to code that can be passed to run; in some cases, you might want what evaluate does in separate steps, such as when compiling on the server and running on the client.

    Expand example

    With a module example.js:

    import {compile} from '@mdx-js/mdx'
    
    const code = 'export const no = 3.14\n\n# hi {no}'
    
    console.log(String(await compile(code, {outputFormat: 'program'}))) // Default.
    console.log(String(await compile(code, {outputFormat: 'function-body'})))

    …yields:

    import {jsx as _jsx, jsxs as _jsxs} from 'react/jsx-runtime'
    export const no = 3.14
    function _createMdxContent(props) { /* … */ }
    export default function MDXContent(props = {}) { /* … */ }
    'use strict'
    const {Fragment: _Fragment, jsx: _jsx} = arguments[0]
    const no = 3.14
    function _createMdxContent(props) { /* … */ }
    function MDXContent(props = {}) { /* … */ }
    return {no, default: MDXContent}

    The 'program' format will use import statements to import the runtime (and optionally provider) and use an export statement to yield the MDXContent component.

    The 'function-body' format will get the runtime (and optionally provider) from arguments[0], rewrite export statements, and use a return statement to yield what was exported.

  • mdExtensions (Array<string>, default: ['.md', '.markdown', '.mdown', '.mkdn', '.mkd', '.mdwn', '.mkdown', '.ron']) — list of markdown extensions, with dot affects § Integrations

  • mdxExtensions (Array<string>, default: ['.mdx']) — list of MDX extensions, with dot; affects § Integrations

  • pragma (string, default: 'React.createElement') — pragma for JSX, used in the classic runtime as an identifier for function calls: <x /> to React.createElement('x'); when changing this, you should also define pragmaFrag and pragmaImportSource too

    Note: support for the classic runtime is deprecated and will likely be removed in the next major version.

    Expand example

    If file is the contents of example.mdx from § Use, then:

    compile(file, {
      jsxRuntime: 'classic',
      pragma: 'preact.createElement',
      pragmaFrag: 'preact.Fragment',
      pragmaImportSource: 'preact/compat'
    })

    …yields this difference:

    -import React from 'react'
    +import preact from 'preact/compat'
    
    export function Thing() {
    -  return React.createElement(React.Fragment, null, 'World!')
    +  return preact.createElement(preact.Fragment, null, 'World!')
    }
    …
  • pragmaFrag (string, default: 'React.Fragment') — pragma for fragment symbol, used in the classic runtime as an identifier for unnamed calls: <> to React.createElement(React.Fragment); when changing this, you should also define pragma and pragmaImportSource too

    Note: support for the classic runtime is deprecated and will likely be removed in the next major version.

  • pragmaImportSource (string, default: 'react') — where to import the identifier of pragma from, used in the classic runtime; to illustrate, when pragma is 'a.b' and pragmaImportSource is 'c' the following will be generated: import a from 'c' and things such as a.b('h1', {}); when changing this, you should also define pragma and pragmaFrag too

    Note: support for the classic runtime is deprecated and will likely be removed in the next major version.

  • providerImportSource (string, optional, example: '@mdx-js/react') — place to import a provider from; normally it’s used for runtimes that support context (React, Preact), but it can be used to inject components into the compiled code; the module must export and identifier useMDXComponents which is called without arguments to get an object of components (see UseMdxComponents)

    Expand example

    If file is the contents of example.mdx from § Use, then:

    compile(file, {providerImportSource: '@mdx-js/react'})

    …yields this difference:

    import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs} from 'react/jsx-runtime'
    +import {useMDXComponents as _provideComponents} from '@mdx-js/react'
    
    export function Thing() {
      return _jsx(_Fragment, {children: 'World'})
    }
    
    function _createMdxContent(props) {
      const _components = {
        h1: 'h1',
    +    ..._provideComponents(),
        ...props.components
      }
      return _jsxs(_components.h1, {children: ['Hello ', _jsx(Thing, {})]})
    }
    
    export default function MDXContent(props = {}) {
    -  const {wrapper: MDXLayout} = props.components || {}
    +  const {wrapper: MDXLayout} = {
    +    ..._provideComponents(),
    +    ...props.components
    +  }
    
      return MDXLayout
        ? _jsx(MDXLayout, {...props, children: _jsx(_createMdxContent, {})})
        : _createMdxContent()
  • recmaPlugins (PluggableList from unified, optional) — list of recma plugins

    Expand example
    import recmaMdxIsMdxComponent from 'recma-mdx-is-mdx-component'
    
    await compile(file, {recmaPlugins: [recmaMdxIsMdxComponent]})
  • rehypePlugins (PluggableList from unified, optional) — list of rehype plugins

    Expand example
    import rehypeKatex from 'rehype-katex' // Render math with KaTeX.
    import remarkMath from 'remark-math' // Support math like `$so

    __INLINE_CODE_0__

    Build Coverage Downloads Size Sponsors Backers Chat

    MDX compiler.

    Contents

    What is this?

    This package is a compiler that turns MDX into JavaScript. It can also evaluate MDX code.

    When should I use this?

    This is the core compiler for turning MDX into JavaScript which gives you the most control. If you’re using a bundler (Rollup, esbuild, webpack), a site builder (Next.js), or build system (Vite) which comes with a bundler, you’re better off using an integration: see § Integrations.

    Install

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

    npm install @mdx-js/mdx

    In Deno with __INLINE_CODE_17__:

    import {compile} from 'https://esm.sh/@mdx-js/mdx@3'

    In browsers with __INLINE_CODE_18__:

    <script type="module">
      import {compile} from 'https://esm.sh/@mdx-js/mdx@3?bundle'
    </script>

    Use

    Say we have an MDX document, __INLINE_CODE_19__:

    export function Thing() {
      return <>World!</>
    }
    
    # Hello, <Thing />

    …and some code in __INLINE_CODE_20__ to compile __INLINE_CODE_21__ to JavaScript:

    import fs from 'node:fs/promises'
    import {compile} from '@mdx-js/mdx'
    
    const compiled = await compile(await fs.readFile('example.mdx'))
    
    console.log(String(compiled))

    Yields roughly:

    import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs} from 'react/jsx-runtime'
    
    export function Thing() {
      return _jsx(_Fragment, {children: 'World!'})
    }
    
    function _createMdxContent(props) {
      const _components = {h1: 'h1', ...props.components}
      return _jsxs(_components.h1, {children: ['Hello, ', _jsx(Thing, {})]})
    }
    
    export default function MDXContent(props = {}) {
      const {wrapper: MDXLayout} = props.components || {}
      return MDXLayout
        ? _jsx(MDXLayout, {...props, children: _jsx(_createMdxContent, {...props})})
        : _createMdxContent(props)
    }

    See § Using MDX for more on how MDX work and how to use the result.

    API

    This package exports the following identifiers: __INLINE_CODE_22__, __INLINE_CODE_23__, __INLINE_CODE_24__, __INLINE_CODE_25__, __INLINE_CODE_26__, __INLINE_CODE_27__, __INLINE_CODE_28__, and __INLINE_CODE_29__. There is no default export.

    __INLINE_CODE_30__

    Compile MDX to JS.

    Parameters
    Returns

    Promise to compiled file (__INLINE_CODE_36__).

    Examples

    The input value for __INLINE_CODE_37__ can be many different things. You can pass a __INLINE_CODE_38__, __INLINE_CODE_39__ in UTF-8, __INLINE_CODE_40__, or anything that can be given to __INLINE_CODE_41__.

    import {compile} from '@mdx-js/mdx'
    import {VFile} from 'vfile'
    
    await compile(':)')
    await compile(Buffer.from(':-)'))
    await compile({path: 'path/to/file.mdx', value: '🥳'})
    await compile(new VFile({path: 'path/to/file.mdx', value: '🤭'}))

    The output __INLINE_CODE_42__ can be used to access more than the generated code:

    import {compile} from '@mdx-js/mdx'
    import remarkPresetLintConsistent from 'remark-preset-lint-consistent' // Lint rules to check for consistent markdown.
    import {reporter} from 'vfile-reporter'
    
    const file = await compile('*like this* or _like this_?', {remarkPlugins: [remarkPresetLintConsistent]})
    
    console.error(reporter(file))

    Yields:

      1:16-1:27  warning  Emphasis should use `*` as a marker  emphasis-marker  remark-lint
    
    ⚠ 1 warning
    __INLINE_CODE_43__

    Synchronously compile MDX to JS.

    When possible please use the async __INLINE_CODE_44__.

    Parameters
    Returns

    Compiled file (__INLINE_CODE_50__).

    __INLINE_CODE_51__

    Create a processor to compile markdown or MDX to JavaScript.

    Note: __INLINE_CODE_52__ is not allowed in __INLINE_CODE_53__.

    Parameters
    Returns

    Processor (__INLINE_CODE_56__ from __INLINE_CODE_57__).

    __INLINE_CODE_58__

    Compile and run MDX.

    When you trust your content, __INLINE_CODE_59__ can work. When possible, use __INLINE_CODE_60__, write to a file, and then run with Node or use one of the § Integrations.

    Danger: it’s called evaluate because it __INLINE_CODE_61__s JavaScript.

    Parameters
    Returns

    Promise to a module (__INLINE_CODE_67__ from __INLINE_CODE_68__).

    The result is an object with a __INLINE_CODE_69__ field set to the component; anything else that was exported is available too. For example, assuming the contents of __INLINE_CODE_70__ from § Use was in __INLINE_CODE_71__, then:

    import {evaluate} from '@mdx-js/mdx'
    import * as runtime from 'react/jsx-runtime'
    
    console.log(await evaluate(file, runtime))

    …yields:

    {Thing: [Function: Thing], default: [Function: MDXContent]}
    Notes

    Compiling (and running) MDX takes time.

    If you are live-rendering a string of MDX that often changes using a virtual DOM based framework (such as React), one performance improvement is to call the __INLINE_CODE_72__ component yourself. The reason is that the __INLINE_CODE_73__ creates a new function each time, which cannot be diffed:

     const {default: MDXContent} = await evaluate('…')
    
    -<MDXContent {...props} />
    +MDXContent(props)
    __INLINE_CODE_74__

    Compile and run MDX, synchronously.

    When possible please use the async __INLINE_CODE_75__.

    Danger: it’s called evaluate because it __INLINE_CODE_76__s JavaScript.

    Parameters
    Returns

    Module (__INLINE_CODE_82__ from __INLINE_CODE_83__).

    __INLINE_CODE_84__

    List of node types made by __INLINE_CODE_85__, which have to be passed through untouched from the mdast tree to the hast tree (__INLINE_CODE_86__).

    __INLINE_CODE_87__

    Run code compiled with __INLINE_CODE_88__.

    Danger: this __INLINE_CODE_89__s JavaScript.

    Parameters
    Returns

    Promise to a module (__INLINE_CODE_95__ from __INLINE_CODE_96__); the result is an object with a __INLINE_CODE_97__ field set to the component; anything else that was exported is available too.

    Example

    On the server:

    import {compile} from '@mdx-js/mdx'
    
    const code = String(await compile('# hi', {outputFormat: 'function-body'}))
    // To do: send `code` to the client somehow.

    On the client:

    import {run} from '@mdx-js/mdx'
    import * as runtime from 'react/jsx-runtime'
    
    const code = '' // To do: get `code` from server somehow.
    
    const {default: Content} = await run(code, {...runtime, baseUrl: import.meta.url})
    
    console.log(Content)

    …yields:

    [Function: MDXContent]
    __INLINE_CODE_98__

    Run code, synchronously.

    When possible please use the async __INLINE_CODE_99__.

    Danger: this __INLINE_CODE_100__s JavaScript.

    Parameters
    Returns

    Module (__INLINE_CODE_106__ from __INLINE_CODE_107__).

    __INLINE_CODE_108__

    Configuration for __INLINE_CODE_109__ (TypeScript type).

    __INLINE_CODE_110__ is the same as __INLINE_CODE_111__ with the exception that the __INLINE_CODE_112__ option supports a __INLINE_CODE_113__ value, which is the default. The __INLINE_CODE_114__ format means to use __INLINE_CODE_115__ for files with an extension in __INLINE_CODE_116__ and __INLINE_CODE_117__ otherwise.

    Type
    /**
     * Configuration for `compile`
     */
    type CompileOptions = Omit<ProcessorOptions, 'format'> & {
      /**
       * Format of `file` (default: `'detect'`).
       */
      format?: 'detect' | 'md' | 'mdx' | null | undefined
    }
    __INLINE_CODE_118__

    Configuration for __INLINE_CODE_119__ (TypeScript type).

    __INLINE_CODE_120__ is the same as __INLINE_CODE_121__, except that the options __INLINE_CODE_122__, __INLINE_CODE_123__, __INLINE_CODE_124__, __INLINE_CODE_125__, __INLINE_CODE_126__, __INLINE_CODE_127__, __INLINE_CODE_128__, __INLINE_CODE_129__, and __INLINE_CODE_130__ are not allowed, and that __INLINE_CODE_131__ are also used.

    Type
    /**
     * Configuration for `evaluate`.
     */
    type EvaluateOptions = Omit<
      CompileOptions,
      | 'baseUrl' // Note that this is also in `RunOptions`.
      | 'jsx'
      | 'jsxImportSource'
      | 'jsxRuntime'
      | 'outputFormat'
      | 'pragma'
      | 'pragmaFrag'
      | 'pragmaImportSource'
      | 'providerImportSource'
    > &
      RunOptions
    __INLINE_CODE_132__

    Represent the children, typically a symbol (TypeScript type).

    Type
    type Fragment = unknown
    __INLINE_CODE_133__

    Create a production element (TypeScript type).

    Parameters
    • __INLINE_CODE_134__ (__INLINE_CODE_135__) — element type: __INLINE_CODE_136__ symbol, tag name (__INLINE_CODE_137__), component
    • __INLINE_CODE_138__ (__INLINE_CODE_139__) — element properties and __INLINE_CODE_140__
    • __INLINE_CODE_141__ (__INLINE_CODE_142__ or __INLINE_CODE_143__) — key to use
    Returns

    Element from your framework (__INLINE_CODE_144__).

    __INLINE_CODE_145__

    Create a development element (TypeScript type).

    Parameters
    • __INLINE_CODE_146__ (__INLINE_CODE_147__) — element type: __INLINE_CODE_148__ symbol, tag name (__INLINE_CODE_149__), component
    • __INLINE_CODE_150__ (__INLINE_CODE_151__) — element properties and __INLINE_CODE_152__
    • __INLINE_CODE_153__ (__INLINE_CODE_154__ or __INLINE_CODE_155__) — key to use
    • __INLINE_CODE_156__ (__INLINE_CODE_157__) — whether two or more children are passed (in an array), which is whether __INLINE_CODE_158__ or __INLINE_CODE_159__ would be used
    • __INLINE_CODE_160__ (__INLINE_CODE_161__) — info about source
    • __INLINE_CODE_162__ (__INLINE_CODE_163__) — context object (__INLINE_CODE_164__)
    __INLINE_CODE_165__

    Configuration for __INLINE_CODE_166__ (TypeScript type).

    Fields
    • __INLINE_CODE_167__ (__INLINE_CODE_168__ from __INLINE_CODE_169__, optional) — add a source map (object form) as the __INLINE_CODE_170__ field on the resulting file

      Expand example

      Assuming __INLINE_CODE_171__ from § Use exists, then:

      import fs from 'node:fs/promises'
      import {compile} from '@mdx-js/mdx'
      import {SourceMapGenerator} from 'source-map'
      
      const file = await compile(
        {path: 'example.mdx', value: await fs.readFile('example.mdx')},
        {SourceMapGenerator}
      )
      
      console.log(file.map)

      …yields:

      {
        file: 'example.mdx',
        mappings: ';;aAAaA,QAAQ;YAAQ;;;;;;;;iBAE3B',
        names: ['Thing'],
        sources: ['example.mdx'],
        version: 3
      }
    • __INLINE_CODE_172__ (__INLINE_CODE_173__ or __INLINE_CODE_174__, optional, example: __INLINE_CODE_175__) — use this URL as __INLINE_CODE_176__ and resolve __INLINE_CODE_177__ and __INLINE_CODE_178__ relative to it

      Expand example

      Say we have a module __INLINE_CODE_179__:

      import {compile} from '@mdx-js/mdx'
      
      const code = 'export {number} from "./data.js"\n\n# hi'
      const baseUrl = 'https://a.full/url' // Typically `import.meta.url`
      
      console.log(String(await compile(code, {baseUrl})))

      …now running __INLINE_CODE_180__ yields:

      import {jsx as _jsx} from 'react/jsx-runtime'
      export {number} from 'https://a.full/data.js'
      function _createMdxContent(props) { /* … */ }
      export default function MDXContent(props = {}) { /* … */ }
    • __INLINE_CODE_181__ (__INLINE_CODE_182__, default: __INLINE_CODE_183__) — whether to add extra info to error messages in generated code and use the development automatic JSX runtime (__INLINE_CODE_184__ and __INLINE_CODE_185__ from __INLINE_CODE_186__); when using the webpack loader (__INLINE_CODE_187__) or the Rollup integration (__INLINE_CODE_188__) through Vite, this is automatically inferred from how you configure those tools

      Expand example

      Say we had some MDX that references a component that can be passed or provided at runtime:

      **Note**<NoteIcon />: some stuff.

      And a module to evaluate that:

      import fs from 'node:fs/promises'
      import {evaluate} from '@mdx-js/mdx'
      import * as runtime from 'react/jsx-runtime'
      
      const path = 'example.mdx'
      const value = await fs.readFile(path)
      const MDXContent = (await evaluate({path, value}, {...runtime, baseUrl: import.meta.url})).default
      
      console.log(MDXContent({}))

      …running that would normally (production) yield:

      Error: Expected component `NoteIcon` to be defined: you likely forgot to import, pass, or provide it.
          at _missingMdxReference (eval at run (…/@mdx-js/mdx/lib/run.js:18:10), <anonymous>:27:9)
          at _createMdxContent (eval at run (…/@mdx-js/mdx/lib/run.js:18:10), <anonymous>:15:20)
          at MDXContent (eval at run (…/@mdx-js/mdx/lib/run.js:18:10), <anonymous>:9:9)
          at main (…/example.js:11:15)

      …but if we add __INLINE_CODE_189__ to our example:

      @@ -7,6 +7,6 @@
      import fs from 'node:fs/promises'
      -import * as runtime from 'react/jsx-runtime'
      +import * as runtime from 'react/jsx-dev-runtime'
      import {evaluate} from '@mdx-js/mdx'
      
      const path = 'example.mdx'
      const value = await fs.readFile(path)
      -const MDXContent = (await evaluate({path, value}, {...runtime, baseUrl: import.meta.url})).default
      +const MDXContent = (await evaluate({path, value}, {development: true, ...runtime, baseUrl: import.meta.url})).default
      
      console.log(MDXContent({}))

      …and we’d run it again, we’d get:

      Error: Expected component `NoteIcon` to be defined: you likely forgot to import, pass, or provide it.
      It’s referenced in your code at `1:9-1:21` in `example.mdx`
      provide it.
          at _missingMdxReference (eval at run (…/@mdx-js/mdx/lib/run.js:18:10), <anonymous>:27:9)
          at _createMdxContent (eval at run (…/@mdx-js/mdx/lib/run.js:18:10), <anonymous>:15:20)
          at MDXContent (eval at run (…/@mdx-js/mdx/lib/run.js:18:10), <anonymous>:9:9)
          at main (…/example.js:11:15)
    • __INLINE_CODE_190__ (__INLINE_CODE_191__ or __INLINE_CODE_192__, default: __INLINE_CODE_193__) — casing to use for attribute names; HTML casing is for example __INLINE_CODE_194__, __INLINE_CODE_195__, __INLINE_CODE_196__; React casing is for example __INLINE_CODE_197__, __INLINE_CODE_198__, __INLINE_CODE_199__; for JSX components written in MDX, the author has to be aware of which framework they use and write code accordingly; for AST nodes generated by this project, this option configures it

    • __INLINE_CODE_200__ (__INLINE_CODE_201__ or __INLINE_CODE_202__, default: __INLINE_CODE_203__) — format of the file; __INLINE_CODE_204__ means treat as markdown and __INLINE_CODE_205__ means treat as MDX

      Expand example
      compile('…') // Seen as MDX.
      compile('…', {format: 'mdx'}) // Seen as MDX.
      compile('…', {format: 'md'}) // Seen as markdown.
    • __INLINE_CODE_206__ (__INLINE_CODE_207__, default: __INLINE_CODE_208__) — whether to keep JSX; the default is to compile JSX away so that the resulting file is immediately runnable.

      Expand example

      If __INLINE_CODE_209__ is the contents of __INLINE_CODE_210__ from § Use, then:

      compile(file, {jsx: true})

      …yields this difference:

      -import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs} from 'react/jsx-runtime'
      +/*@jsxRuntime automatic*/
      +/*@jsxImportSource react*/
      
      export function Thing() {
      -  return _jsx(_Fragment, {children: 'World'})
      +  return <>World!</>
      }
      
      function _createMdxContent(props) {
        const _components = {
          h1: 'h1',
          ...props.components
        }
      -  return _jsxs(_components.h1, {children: ['Hello ', _jsx(Thing, {})]})
      +  return <_components.h1>{"Hello "}<Thing /></_components.h1>
      }
      
      export default function MDXContent(props = {}) {
        const {wrapper: MDXLayout} = props.components || {}
        return MDXLayout
      -    ? _jsx(MDXLayout, {
      -        ...props,
      -        children: _jsx(_createMdxContent, props)
      -      })
      +    ? <MDXLayout {...props}><_createMdxContent {...props} /></MDXLayout>
          : _createMdxContent(props)
      }
      }
    • __INLINE_CODE_211__ (__INLINE_CODE_212__, default: __INLINE_CODE_213__) — place to import automatic JSX runtimes from; when in the __INLINE_CODE_214__ runtime, this is used to define an import for __INLINE_CODE_215__, __INLINE_CODE_216__, __INLINE_CODE_217__, and __INLINE_CODE_218__

      Expand example

      If __INLINE_CODE_219__ is the contents of __INLINE_CODE_220__ from § Use, then:

      compile(file, {jsxImportSource: 'preact'})

      …yields this difference:

      -import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs} from 'react/jsx-runtime'
      +import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from 'preact/jsx-runtime'
    • __INLINE_CODE_221__ (__INLINE_CODE_222__ or __INLINE_CODE_223__, default: __INLINE_CODE_224__) — JSX runtime to use; the automatic runtime compiles to __INLINE_CODE_225__; the classic runtime compiles to calls such as __INLINE_CODE_226__

      Note: support for the classic runtime is deprecated and will likely be removed in the next major version.

      Expand example

      If __INLINE_CODE_227__ is the contents of __INLINE_CODE_228__ from § Use, then:

      compile(file, {jsxRuntime: 'classic'})

      …yields this difference:

      -import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs} from 'react/jsx-runtime'
      +import React from 'react'
      
      export function Thing() {
      -  return _jsx(_Fragment, {children: 'World'})
      +  return React.createElement(React.Fragment, null, 'World!')
      }
      …
    • __INLINE_CODE_229__ (__INLINE_CODE_230__ or __INLINE_CODE_231__, default: __INLINE_CODE_232__) — output format to generate; in most cases __INLINE_CODE_233__ should be used, it results in a whole program; internally __INLINE_CODE_234__ uses __INLINE_CODE_235__ to compile to code that can be passed to __INLINE_CODE_236__; in some cases, you might want what __INLINE_CODE_237__ does in separate steps, such as when compiling on the server and running on the client.

      Expand example

      With a module __INLINE_CODE_238__:

      import {compile} from '@mdx-js/mdx'
      
      const code = 'export const no = 3.14\n\n# hi {no}'
      
      console.log(String(await compile(code, {outputFormat: 'program'}))) // Default.
      console.log(String(await compile(code, {outputFormat: 'function-body'})))

      …yields:

      import {jsx as _jsx, jsxs as _jsxs} from 'react/jsx-runtime'
      export const no = 3.14
      function _createMdxContent(props) { /* … */ }
      export default function MDXContent(props = {}) { /* … */ }
      'use strict'
      const {Fragment: _Fragment, jsx: _jsx} = arguments[0]
      const no = 3.14
      function _createMdxContent(props) { /* … */ }
      function MDXContent(props = {}) { /* … */ }
      return {no, default: MDXContent}

      The __INLINE_CODE_239__ format will use import statements to import the runtime (and optionally provider) and use an export statement to yield the __INLINE_CODE_240__ component.

      The __INLINE_CODE_241__ format will get the runtime (and optionally provider) from __INLINE_CODE_242__, rewrite export statements, and use a return statement to yield what was exported.

    • __INLINE_CODE_243__ (__INLINE_CODE_244__, default: __INLINE_CODE_245__) — list of markdown extensions, with dot affects § Integrations

    • __INLINE_CODE_246__ (__INLINE_CODE_247__, default: __INLINE_CODE_248__) — list of MDX extensions, with dot; affects § Integrations

    • __INLINE_CODE_249__ (__INLINE_CODE_250__, default: __INLINE_CODE_251__) — pragma for JSX, used in the classic runtime as an identifier for function calls: __INLINE_CODE_252__ to __INLINE_CODE_253__; when changing this, you should also define __INLINE_CODE_254__ and __INLINE_CODE_255__ too

      Note: support for the classic runtime is deprecated and will likely be removed in the next major version.

      Expand example

      If __INLINE_CODE_256__ is the contents of __INLINE_CODE_257__ from § Use, then:

      compile(file, {
        jsxRuntime: 'classic',
        pragma: 'preact.createElement',
        pragmaFrag: 'preact.Fragment',
        pragmaImportSource: 'preact/compat'
      })

      …yields this difference:

      -import React from 'react'
      +import preact from 'preact/compat'
      
      export function Thing() {
      -  return React.createElement(React.Fragment, null, 'World!')
      +  return preact.createElement(preact.Fragment, null, 'World!')
      }
      …
    • __INLINE_CODE_258__ (__INLINE_CODE_259__, default: __INLINE_CODE_260__) — pragma for fragment symbol, used in the classic runtime as an identifier for unnamed calls: __INLINE_CODE_261__ to __INLINE_CODE_262__; when changing this, you should also define __INLINE_CODE_263__ and __INLINE_CODE_264__ too

      Note: support for the classic runtime is deprecated and will likely be removed in the next major version.

    • __INLINE_CODE_265__ (__INLINE_CODE_266__, default: __INLINE_CODE_267__) — where to import the identifier of __INLINE_CODE_268__ from, used in the classic runtime; to illustrate, when __INLINE_CODE_269__ is __INLINE_CODE_270__ and __INLINE_CODE_271__ is __INLINE_CODE_272__ the following will be generated: __INLINE_CODE_273__ and things such as __INLINE_CODE_274__; when changing this, you should also define __INLINE_CODE_275__ and __INLINE_CODE_276__ too

      Note: support for the classic runtime is deprecated and will likely be removed in the next major version.

    • __INLINE_CODE_277__ (__INLINE_CODE_278__, optional, example: __INLINE_CODE_279__) — place to import a provider from; normally it’s used for runtimes that support context (React, Preact), but it can be used to inject components into the compiled code; the module must export and identifier __INLINE_CODE_280__ which is called without arguments to get an object of components (see __INLINE_CODE_281__)

      Expand example

      If __INLINE_CODE_282__ is the contents of __INLINE_CODE_283__ from § Use, then:

      compile(file, {providerImportSource: '@mdx-js/react'})

      …yields this difference:

      import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs} from 'react/jsx-runtime'
      +import {useMDXComponents as _provideComponents} from '@mdx-js/react'
      
      export function Thing() {
        return _jsx(_Fragment, {children: 'World'})
      }
      
      function _createMdxContent(props) {
        const _components = {
          h1: 'h1',
      +    ..._provideComponents(),
          ...props.components
        }
        return _jsxs(_components.h1, {children: ['Hello ', _jsx(Thing, {})]})
      }
      
      export default function MDXContent(props = {}) {
      -  const {wrapper: MDXLayout} = props.components || {}
      +  const {wrapper: MDXLayout} = {
      +    ..._provideComponents(),
      +    ...props.components
      +  }
      
        return MDXLayout
          ? _jsx(MDXLayout, {...props, children: _jsx(_createMdxContent, {})})
          : _createMdxContent()
    • __INLINE_CODE_284__ (__INLINE_CODE_285__ from __INLINE_CODE_286__, optional) — list of recma plugins

      Expand example
      import recmaMdxIsMdxComponent from 'recma-mdx-is-mdx-component'
      
      await compile(file, {recmaPlugins: [recmaMdxIsMdxComponent]})
    • __INLINE_CODE_287__ (__INLINE_CODE_288__ from __INLINE_CODE_289__, optional) — list of rehype plugins

      Expand example. await compile(file, {rehypePlugins: [rehypeKatex], remarkPlugins: [remarkMath]}) await compile(file, { // A plugin with options: rehypePlugins: [[rehypeKatex, {strict: true, throwOnError: true}]], remarkPlugins: [remarkMath] })
  • remarkPlugins (PluggableList from unified, optional) — list of remark plugins

    Expand example
    import remarkFrontmatter from 'remark-frontmatter' // YAML and such.
    import remarkGfm from 'remark-gfm' // Tables, footnotes, strikethrough, task lists, literal URLs.
    
    await compile(file, {remarkPlugins: [remarkGfm]}) // One plugin.
    await compile(file, {remarkPlugins: [[remarkFrontmatter, 'toml']]}) // A plugin with options.
    await compile(file, {remarkPlugins: [remarkGfm, remarkFrontmatter]}) // Two plugins.
    await compile(file, {remarkPlugins: [[remarkGfm, {singleTilde: false}], remarkFrontmatter]}) // Two plugins, first w/ options.
  • remarkRehypeOptions (Options from remark-rehype, optional) — options to pass through to remark-rehype; in particular, you might want to pass configuration for footnotes if your content is not in English; the option allowDangerousHtml will always be set to true and the MDX nodes (see nodeTypes) are passed through.

    Expand example
    compile({value: '…'}, {remarkRehypeOptions: {clobberPrefix: 'comment-1'}})
  • stylePropertyNameCase ('css' or 'dom, default: 'dom') — casing to use for property names in style objects; CSS casing is for example background-color and -webkit-line-clamp; DOM casing is for example backgroundColor and WebkitLineClamp; for JSX components written in MDX, the author has to be aware of which framework they use and write code accordingly; for AST nodes generated by this project, this option configures it

  • tableCellAlignToStyle (boolean, default: true) — turn obsolete align properties on td and th into CSS style properties

RunOptions

Configuration to run compiled code (TypeScript type).

Fragment, jsx, and jsxs are used when the code is compiled in production mode (development: false). Fragment and jsxDEV are used when compiled in development mode (development: true). useMDXComponents is used when the code is compiled with providerImportSource: '#' (the exact value of this compile option doesn’t matter).

Fields
  • Fragment (Fragment, required) — symbol to use for fragments
  • baseUrl (URL or string, optional, example: import.meta.url) — use this URL as import.meta.url and resolve import and export … from relative to it; this option can also be given at compile time in CompileOptions; you should pass this (likely at runtime), as you might get runtime errors when using import.meta.url / import / export … from otherwise
  • jsx (Jsx, optional) — function to generate an element with static children in production mode
  • jsxDEV (JsxDev, optional) — function to generate an element in development mode
  • jsxs (Jsx, optional) — function to generate an element with dynamic children in production mode
  • useMDXComponents (UseMdxComponents, optional) — function to get components to use
Examples

A /jsx-runtime module will expose Fragment, jsx, and jsxs:

import * as runtime from 'react/jsx-runtime'

const {default: Content} = await evaluate('# hi', {...runtime, baseUrl: import.meta.url, ...otherOptions})

A /jsx-dev-runtime module will expose Fragment and jsxDEV:

import * as runtime from 'react/jsx-dev-runtime'

const {default: Content} = await evaluate('# hi', {development: true, baseUrl: import.meta.url, ...runtime, ...otherOptions})

Our providers will expose useMDXComponents:

import * as provider from '@mdx-js/react'
import * as runtime from 'react/jsx-runtime'

const {default: Content} = await evaluate('# hi', {...provider, ...runtime, baseUrl: import.meta.url, ...otherOptions})
UseMdxComponents

Get components (TypeScript type).

Parameters

There are no parameters.

Returns

Components (MDXComponents from mdx/types.js).

Types

This package is fully typed with TypeScript. It exports the additional types CompileOptions, EvaluateOptions, Fragment, Jsx, JsxDev, ProcessorOptions, RunOptions, and UseMdxComponents.

For types of evaluated MDX to work, make sure the TypeScript JSX namespace is typed. This is done by installing and using the types of your framework, such as @types/react. See § Types on our website for information.

Architecture

To understand what this project does, it’s very important to first understand what unified does: please read through the unifiedjs/unified readme (the part until you hit the API section is required reading).

@mdx-js/mdx is a unified pipeline — wrapped so that most folks don’t need to know about unified. The processor goes through these steps:

  1. parse MDX (serialized markdown with embedded JSX, ESM, and expressions) to mdast (markdown syntax tree)
  2. transform through remark (markdown ecosystem)
  3. transform mdast to hast (HTML syntax tree)
  4. transform through rehype (HTML ecosystem)
  5. transform hast to esast (JS syntax tree)
  6. do the work needed to get a component
  7. transform through recma (JS ecosystem)
  8. serialize esast as JavaScript

The input is MDX. That’s serialized markdown with embedded JSX, ESM, and expressions. In the case of JSX, the tags are intertwined with markdown. The markdown is parsed with micromark/micromark and the embedded JS with one of its extensions micromark/micromark-extension-mdxjs (which in turn uses acorn). Then syntax-tree/mdast-util-from-markdown and its extension syntax-tree/mdast-util-mdx are used to turn the results from the parser into a syntax tree: mdast.

Markdown is closest to the source format. This is where remark plugins come in. Typically, there shouldn’t be much going on here. But perhaps you want to support GFM (tables and such) or frontmatter? Then you can add a plugin here: remark-gfm or remark-frontmatter, respectively.

After markdown, we go to hast (HTML). This transformation is done by syntax-tree/mdast-util-to-hast. Wait, what, why is HTML needed? Part of the reason is that we care about HTML semantics: we want to know that something is an <a>, not whether it’s a link with a resource ([text](url)) or a reference to a defined link definition ([text][id]\n\n[id]: url). So an HTML AST is closer to where we want to go. Another reason is that there are many things folks need when they go MDX -> JS, markdown -> HTML, or even folks who only process their HTML -> HTML: use cases other than MDX. By having a single AST in these cases and writing a plugin that works on that AST, that plugin can supports all these use cases (for example, rehypejs/rehype-highlight for syntax highlighting or rehypejs/rehype-katex for math). So, this is where rehype plugins come in: most of the plugins, probably.

Then we go to JavaScript: esast (JS; an AST which is compatible with estree but looks a bit more like other unist ASTs). This transformation is done by rehype-recma. This is a newer ecosystem. There are some recma plugins already. It’s where @mdx-js/mdx does its thing: where it adds imports/exports, where it compiles JSX away into _jsx() calls, and where it does the other cool things that it provides.

Finally, The output is serialized JavaScript. That final step is done by astring, a small and fast JS generator.

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, @mdx-js/mdx@^3, compatible with Node.js 16.

Security

See § Security on our website for information.

Contribute

See § Contribute on our website for ways to get started. See § Support for ways to get help.

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

License

MIT Compositor and Vercel

Keywords