mdx-js/mdx · error · Error

Missing `pragma` in classic runtime with `pragmaImportSource

Error message

Missing `pragma` in classic runtime with `pragmaImportSource`

What it means

recma-document throws this when the MDX pipeline is configured with `jsxRuntime: 'classic'` together with `pragmaImportSource` but no `pragma` option. In classic JSX runtime the compiler must know the exact identifier to import the JSX factory from (via `pragma`); `pragmaImportSource` only names the module, so without `pragma` it cannot emit a valid import. The library refuses to generate broken code and fails fast.

Source

Thrown at packages/mdx/lib/plugin/recma-document.js:102

    if (jsxRuntime === 'classic' && pragmaFrag) {
      injectPragma(tree, '@jsxFrag', pragmaFrag)
    }

    if (jsxRuntime === 'classic' && pragma) {
      injectPragma(tree, '@jsx', pragma)
    }

    if (jsxRuntime === 'automatic' && jsxImportSource) {
      injectPragma(tree, '@jsxImportSource', jsxImportSource)
    }

    if (jsxRuntime) {
      injectPragma(tree, '@jsxRuntime', jsxRuntime)
    }

    if (jsxRuntime === 'classic' && pragmaImportSource) {
      if (!pragma) {
        throw new Error(
          'Missing `pragma` in classic runtime with `pragmaImportSource`'
        )
      }

      handleEsm({
        type: 'ImportDeclaration',
        specifiers: [
          {
            type: 'ImportDefaultSpecifier',
            local: {type: 'Identifier', name: pragma.split('.')[0]}
          }
        ],
        attributes: [],
        source: {type: 'Literal', value: pragmaImportSource}
      })
    }

    // Find the `export default`, the JSX expression, and leave the rest

View on GitHub (pinned to 685627a819)

Solutions

  1. Add the `pragma` option alongside `pragmaImportSource`, e.g. `pragma: 'h'` for Preact (`pragmaImportSource: 'preact'`).
  2. If you do not need the classic runtime, remove `jsxRuntime: 'classic'` and `pragmaImportSource` and use the default automatic runtime.
  3. If migrating to MDX v3, drop classic-runtime options entirely and configure the JSX runtime via `jsxImportSource` / `development` as described in https://mdxjs.com/migrating/v3/.

Example fix

// before
await compile(file, { jsxRuntime: 'classic', pragmaImportSource: 'preact' })
// after
await compile(file, { jsxRuntime: 'classic', pragma: 'h', pragmaFrag: 'Fragment', pragmaImportSource: 'preact' })
Defensive patterns

Strategy: validation

Validate before calling

const opts = mdxOptions
if (opts?.jsxRuntime === 'classic' && opts.pragmaImportSource && !opts.pragma) {
  throw new Error("pragmaImportSource requires a matching pragma when jsxRuntime is 'classic'")
}

Type guard

function hasClassicPragmaPair(o) {
  return typeof o === 'object' && o !== null &&
    (o.jsxRuntime !== 'classic' || !o.pragmaImportSource || typeof o.pragma === 'string')
}

Try / catch

try {
  await compile(file, mdxOptions)
} catch (err) {
  if (err.message.includes('Missing `pragma` in classic runtime')) {
    console.error('Add `pragma` when using classic JSX runtime with pragmaImportSource')
  } else throw err
}

Prevention

When it happens

Trigger: Calling `compile`/`createProcessor` from `mdx` with `recmaPlugins`/options where `jsxRuntime: 'classic'` and `pragmaImportSource` are set but `pragma` is undefined (e.g. only `pragmaImportSource: 'preact/compat'` given, or `pragma` typo'd/removed).

Common situations: Migrating from MDX v1/v2 to v3 where classic-runtime options were partially carried over; switching to Preact/other JSX libraries and setting `pragmaImportSource` while forgetting `pragma: 'h'`; copying a config snippet that lists `pragmaImportSource` but omits `pragma`.

Understand the failure class

Background: "Must pass :limit option" / "Missing required option" — required option errors explained — this error's family across 41 libraries.

Related errors


AI-assisted analysis of mdx-js/mdx@685627a819 (2026-09-02). Data as JSON: /api/errors/f673b29b11e3397e. Report an issue: GitHub.