mdx-js/mdx · error · Error

Expected `jsx` given to `evaluate`

Error message

Expected `jsx` given to `evaluate`

What it means

In production mode (`development` falsy), the compiled MDX code calls `jsx` for single-child/element creation, so resolveEvaluateOptions requires `jsx` in the evaluate options. Without it the generated program cannot run, and MDX throws this error up front instead of failing later with a ReferenceError.

Source

Thrown at packages/mdx/lib/util/resolve-evaluate-options.js:74

 *   Split options.
 */
export function resolveEvaluateOptions(options) {
  const {
    Fragment,
    baseUrl,
    development,
    jsx,
    jsxDEV,
    jsxs,
    useMDXComponents,
    ...rest
  } = options || {}

  if (!Fragment) throw new Error('Expected `Fragment` given to `evaluate`')
  if (development) {
    if (!jsxDEV) throw new Error('Expected `jsxDEV` given to `evaluate`')
  } else {
    if (!jsx) throw new Error('Expected `jsx` given to `evaluate`')
    if (!jsxs) throw new Error('Expected `jsxs` given to `evaluate`')
  }

  return {
    compiletime: {
      ...rest,
      development,
      outputFormat: 'function-body',
      providerImportSource: useMDXComponents ? '#' : undefined
    },
    runtime: {Fragment, baseUrl, jsx, jsxDEV, jsxs, useMDXComponents}
  }
}

View on GitHub (pinned to 685627a819)

Solutions

  1. Add `jsx` from 'react/jsx-runtime' (or your library's equivalent) to the evaluate options.
  2. Ensure `development` correctly reflects the runtime you imported: prod needs `jsx`+`jsxs`, dev needs `jsxDEV`.
  3. Import the complete runtime object (`Fragment, jsx, jsxs`) together so none can be dropped.

Example fix

// before
await evaluate(code, { Fragment, jsxs })
// after
import { Fragment, jsx, jsxs } from 'react/jsx-runtime'
await evaluate(code, { Fragment, jsx, jsxs })
Defensive patterns

Strategy: validation

Validate before calling

if (!development && !runtime.jsx) {
  throw new Error('evaluate options require `jsx` when development is falsy')
}

Type guard

function hasJsx(rt) {
  return typeof rt === 'object' && rt !== null && typeof rt.jsx === 'function'
}

Try / catch

try {
  const result = await evaluate(code, runtime)
} catch (err) {
  if (err.message === 'Expected `jsx` given to `evaluate`') {
    console.error('Provide jsx from your jsx-runtime in evaluate options')
  } else throw err
}

Prevention

When it happens

Trigger: Calling `evaluate(code, { Fragment, jsxs })` without `jsx`; providing only `jsxDEV` while leaving `development` falsy; spreading a partial runtime object that lacks `jsx`.

Common situations: Hand-rolled runtime objects in Node scripts evaluating MDX; tree-shaking or bundling dropping the `jsx` import as unused; mixing dev/prod exports (passing jsxDEV but not jsx/jsxs).

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/599245c13d0f4312. Report an issue: GitHub.