---
title: "MDX Configuration Preset Loading"
description: "The execution flow from createMDX through applyMdxPreset bridges Next.js configuration integration with Fumadocs' content management engine. When initializing MDX for a Next.js project, the core fr..."
last_updated: "2026-10-12T07:53:59.756147+00:00"
canonical_url: "https://www.doc0.dev/docs/e8872a72-1909-479c-b585-dc74c6e26726/technical/how-it-works/mdx-configuration-preset-loading"
---

<details>
<summary>Relevant source files</summary>

The following files were used as context for generating this wiki page:

- [packages/mdx/src/next/index.ts](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/mdx/src/next/index.ts)
- [packages/mdx/src/config/load-from-file.ts](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/mdx/src/config/load-from-file.ts)
- [packages/mdx/src/config/build.ts](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/mdx/src/config/build.ts)
- [packages/mdx/src/config/preset.ts](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/mdx/src/config/preset.ts)
</details>

## Overview

The execution flow from `createMDX` through `applyMdxPreset` bridges Next.js configuration integration with Fumadocs' content management engine. When initializing MDX for a Next.js project, the core framework compiles user-defined source configurations, builds collections, and automatically configures remark and rehype processor options. This ensures that markdown and MDX files are parsed correctly across different build environments (bundler vs. runtime).

Sources: [packages/mdx/src/next/index.ts:30-122](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/mdx/src/next/index.ts#L30-L122)

## Execution Flow

### Step 1: createMDX

The process begins when `createMDX` is invoked with optional configuration options (`CreateMDXOptions`). It sets up the Next.js core environment using `createNextCore` and `applyDefaults`, and ensures that initialization occurs only once by checking the `_FUMADOCS_MDX` environment variable. It returns a curried function that injects custom Webpack and Turbopack rules for `.mdx`, `.md`, `.json`, and `.yaml` files into the Next.js configuration.

Sources: [packages/mdx/src/next/index.ts:30-38](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/mdx/src/next/index.ts#L30-L38)

### Step 2: init

Invoked asynchronously during setup, the `init` function manages core initialization and coordinates the development server lifecycle. It defines internal helper routines (`initOrReload` and `devServer`) to load configurations and watch file changes during local development.

Sources: [packages/mdx/src/next/index.ts:124-182](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/mdx/src/next/index.ts#L124-L182)

### Step 3: devServer

If running in a development environment, `devServer` sets up a file watcher using `chokidar`. It monitors the configuration file and all registered collection directories. When the configuration file changes, the watcher safely closes itself, reloads the configuration, restarts the development server routine, and re-initializes the server watcher.

Sources: [packages/mdx/src/next/index.ts:132-176](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/mdx/src/next/index.ts#L132-L176)

### Step 4: initOrReload

The `initOrReload` function orchestrates core startup by calling `core.init` with the result of loading the configuration file. Once initialized, it instructs the core to emit generated artifacts (such as index files or type definitions) with writing enabled (`write: true`).

Sources: [packages/mdx/src/next/index.ts:125-130](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/mdx/src/next/index.ts#L125-L130)

### Step 5: loadConfig

The `loadConfig` function handles compiling and importing the source configuration file. When the `build` flag is set to true, it triggers `compileConfig` using `esbuild` to bundle the source configuration into a portable ESM module (`.mjs`). It then appends a timestamp query parameter to bust module cache before dynamically importing the compiled config and passing the raw exports to `buildConfig`.

Sources: [packages/mdx/src/config/load-from-file.ts:35-44](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/mdx/src/config/load-from-file.ts#L35-L44)

### Step 6: buildConfig

The `buildConfig` function parses raw configuration exports, mapping collection objects and global settings. It constructs collection instances and exposes a `getMDXOptions` method. When MDX options are requested for a specific collection or environment, it evaluates global or collection-level options and delegates preset generation to `applyMdxPreset`.

Sources: [packages/mdx/src/config/build.ts:118-180](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/mdx/src/config/build.ts#L118-L180)

### Step 7: applyMdxPreset

Finally, `applyMdxPreset` takes the user's MDX options and returns an asynchronous function that resolves processor options for the specified build environment (`bundler` or `runtime`). If the preset is set to `'minimal'`, it returns the options unchanged. Otherwise, it loads `fumadocs-core/mdx-plugins` and configures standard remark plugins (such as `remarkGfm`, `remarkHeading`, `remarkImage`, and `remarkStructure`) and rehype plugins (such as `rehypeCode` and `rehypeToc`), adjusting options based on whether it is targeting a bundler or runtime environment.

Sources: [packages/mdx/src/config/preset.ts:50-132](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/mdx/src/config/preset.ts#L50-L132)

---

## Architecture Diagrams

### Sequence Diagram

```mermaid
sequenceDiagram
    participant Next as Next.js Config
    participant Index as packages/mdx/next
    participant Core as Core Engine
    participant Loader as loadConfig
    participant Builder as buildConfig
    participant Preset as applyMdxPreset

    Next->>Index: createMDX(options)
    Index->>Index: init(isDev, core)
    Index->>Core: initOrReload()
    Core->>Loader: loadConfig(core, true)
    Loader->>Loader: compileConfig(core)
    Loader->>Builder: buildConfig(loaded, cwd)
    Builder->>Preset: applyMdxPreset(options)
    Preset-->>Builder: ProcessorOptions
    Builder-->>Loader: LoadedConfig
    Loader-->>Core: Resolved config
    Core-->>Index: Initialized
```

Sources: [packages/mdx/src/next/index.ts:30-38](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/mdx/src/next/index.ts#L30-L38), [packages/mdx/src/config/load-from-file.ts:35-44](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/mdx/src/config/load-from-file.ts#L35-L44), [packages/mdx/src/config/build.ts:118-180](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/mdx/src/config/build.ts#L118-L180), [packages/mdx/src/config/preset.ts:50-132](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/mdx/src/config/preset.ts#L50-L132)

### Flowchart

```mermaid
flowchart TD
    A[createMDX] --> B[init]
    B --> C{isDev?}
    C -->|Yes| D[devServer & initOrReload]
    C -->|No| E[initOrReload]
    D --> F[loadConfig]
    E --> F[loadConfig]
    F --> G[compileConfig with esbuild]
    G --> H[buildConfig]
    H --> I[applyMdxPreset]
    I --> J[Return ProcessorOptions]
```

Sources: [packages/mdx/src/next/index.ts:30-182](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/mdx/src/next/index.ts#L30-L182), [packages/mdx/src/config/load-from-file.ts:6-44](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/mdx/src/config/load-from-file.ts#L6-L44), [packages/mdx/src/config/build.ts:118-180](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/mdx/src/config/build.ts#L118-L180), [packages/mdx/src/config/preset.ts:50-132](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/mdx/src/config/preset.ts#L50-L132)

---

## Key Observations

- **Cross-Module Boundaries:** The flow bridges Next.js integration hooks (`packages/mdx/src/next/index.ts`) with configuration building (`packages/mdx/src/config/load-from-file.ts` and `build.ts`) and unified plugin management (`packages/mdx/src/config/preset.ts`).
- **Error Handling:** Configuration compilation checks `transformed.errors.length` and throws an error if `esbuild` fails. Dynamic imports and file watcher logic ensure that updates to config files gracefully restart the development environment.
- **Caching & Dynamic Reloading:** `loadConfig` invalidates import caches by appending a millisecond timestamp hash query parameter to the file URL, ensuring fresh configuration loads during development reloads.

Sources: [packages/mdx/src/config/load-from-file.ts:25-41](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/mdx/src/config/load-from-file.ts#L25-L41)

## Sitemap

See the full [sitemap](https://www.doc0.dev/docs/e8872a72-1909-479c-b585-dc74c6e26726/llms.txt) for all pages in this wiki.
