# Gatsby Transformer Remark vs Plugin MDX: Choosing the Right Markdown Engine

> Compare Gatsby Transformer Remark and Gatsby Plugin MDX. Learn when to use each for your Markdown or MDX content in Gatsby projects.

- Repository: [Gatsby/gatsby](https://github.com/gatsbyjs/gatsby)
- Tags: deep-dive
- Published: 2026-03-06

---

**Use `gatsby-transformer-remark` for static Markdown content that only needs HTML conversion, and choose `gatsby-plugin-mdx` when you need to embed React components directly in your Markdown files using JSX syntax.**

The Gatsby ecosystem provides two primary pathways for processing Markdown content, each serving distinct architectural needs. Understanding the difference between `gatsby-transformer-remark` and `gatsby-plugin-mdx` is essential for optimizing your site's build process and content authoring experience. Both plugins transform source files into GraphQL nodes, but they differ fundamentally in parsing engines, node types, and component interoperability according to the Gatsby source code.

## Core Architectural Differences

The primary distinction lies in the parsing engine and output format. According to [`packages/gatsby-transformer-remark/gatsby-node.js`](https://github.com/gatsbyjs/gatsby/blob/main/packages/gatsby-transformer-remark/gatsby-node.js) and [`packages/gatsby-plugin-mdx/src/gatsby-node.ts`](https://github.com/gatsbyjs/gatsby/blob/main/packages/gatsby-plugin-mdx/src/gatsby-node.ts), `gatsby-transformer-remark` operates as a pure transformer plugin, while `gatsby-plugin-mdx` functions as both a transformer and page creator.

| Feature | `gatsby-transformer-remark` | `gatsby-plugin-mdx` |
|---------|-----------------------------|---------------------|
| **Input format** | Pure Markdown (`.md`, `.markdown`) | MDX – Markdown with embedded JSX (`.mdx`, optionally `.md` when configured) |
| **Node type** | `MarkdownRemark` | `Mdx` |
| **Parsing engine** | remark | MDX v2 (via `@mdx-js/mdx`) |
| **Component support** | No native JSX; requires `dangerouslySetInnerHTML` or additional plugins | Native JSX support; imports React components directly |
| **GraphQL fields** | `html`, `excerpt`, `frontmatter`, `tableOfContents` | `body`, `excerpt`, `frontmatter`, `headings`, `tableOfContents` |
| **Page creation** | Requires manual page creation in [`gatsby-node.js`](https://github.com/gatsbyjs/gatsby/blob/main/gatsby-node.js) | Auto-creates pages for `.mdx` files in `src/pages` |

## How gatsby-transformer-remark Works

In [`packages/gatsby-transformer-remark/gatsby-node.js`](https://github.com/gatsbyjs/gatsby/blob/main/packages/gatsby-transformer-remark/gatsby-node.js), the plugin implements the `onCreateNode` API to transform `File` nodes into `MarkdownRemark` nodes. It uses the remark ecosystem for parsing, allowing you to extend functionality through `gatsby-remark-*` plugins.

### Configuration and Usage

Configure the plugin in [`gatsby-config.js`](https://github.com/gatsbyjs/gatsby/blob/main/gatsby-config.js) with remark-specific options:

```javascript
// gatsby-config.js
module.exports = {
  plugins: [
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `blog`,
        path: `${__dirname}/blog`,
      },
    },
    {
      resolve: `gatsby-transformer-remark`,
      options: {
        footnotes: true,
        gfm: true,
        plugins: [
          {
            resolve: `gatsby-remark-prismjs`,
            options: { classPrefix: "language-" },
          },
        ],
      },
    },
  ],
};

```

### GraphQL Schema for MarkdownRemark

Query `MarkdownRemark` nodes to access the generated HTML:

```graphql
{
  allMarkdownRemark(sort: { frontmatter: { date: DESC } }) {
    edges {
      node {
        id
        frontmatter {
          title
          date(formatString: "MMMM DD, YYYY")
        }
        html
        excerpt(pruneLength: 200)
      }
    }
  }
}

```

## How gatsby-plugin-mdx Works

According to [`packages/gatsby-plugin-mdx/src/gatsby-node.ts`](https://github.com/gatsbyjs/gatsby/blob/main/packages/gatsby-plugin-mdx/src/gatsby-node.ts), this plugin creates `Mdx` nodes and handles MDX compilation using MDX v2. It supports both `.mdx` and `.md` extensions (when configured) and integrates deeply with React's component model.

### MDX v2 Architecture

The plugin uses `@mdx-js/mdx` to compile Markdown with JSX into executable JavaScript. This allows you to import and use React components directly within your content files.

### Configuration with gatsbyRemarkPlugins and mdxOptions

Configure MDX processing in `gatsby-config.mjs` (ESM format recommended):

```javascript
// gatsby-config.mjs
import { dirname } from "path";
import { fileURLToPath } from "url";

const __dirname = dirname(fileURLToPath(import.meta.url));

export default {
  plugins: [
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `pages`,
        path: `${__dirname}/src/pages`,
      },
    },
    {
      resolve: `gatsby-plugin-mdx`,
      options: {
        extensions: [`.mdx`, `.md`],
        gatsbyRemarkPlugins: [
          {
            resolve: `gatsby-remark-images`,
            options: { maxWidth: 800 },
          },
        ],
        mdxOptions: {
          remarkPlugins: [require("remark-gfm")],
          rehypePlugins: [require("rehype-slug")],
        },
      },
    },
  ],
};

```

### GraphQL Schema for Mdx

Query `Mdx` nodes to access the raw body and headings:

```graphql
{
  mdx(frontmatter: { slug: { eq: "/about" } }) {
    frontmatter {
      title
    }
    body
    excerpt
    headings {
      depth
      value
    }
  }
}

```

### Rendering MDX Content

Unlike `gatsby-transformer-remark`, which provides pre-rendered HTML, MDX content renders as React children in your page templates:

```jsx
// src/templates/mdx-page.jsx
export default function MdxPage({ data: { mdx }, children }) {
  return (
    <main>
      <h1>{mdx.frontmatter.title}</h1>
      {children} {/* rendered MDX components */}
    </main>
  );
}

```

## When to Use Each Plugin

Choosing between these plugins depends entirely on your content strategy and interactivity requirements.

**Use `gatsby-transformer-remark` when:**

- Your content consists of static Markdown without interactive elements.
- You need the `html` field for RSS feeds, email templates, or SEO meta descriptions that require raw HTML strings.
- You rely on the extensive `gatsby-remark-*` plugin ecosystem for image optimization, syntax highlighting, or automatic link generation.
- Performance is critical for large content volumes where JSX compilation overhead is unnecessary.

**Use `gatsby-plugin-mdx` when:**

- You want to embed React components directly in content files for interactive demos, live code editors, or dynamic data visualizations.
- Your content authors need JSX/TSX support for custom layouts, shortcodes, or component composition.
- You are building marketing pages, tutorials, or documentation that mixes prose with interactive UI elements.
- You want to leverage MDX v2's modern architecture with direct access to `remarkPlugins` and `rehypePlugins` via `mdxOptions`.

## Migration Considerations

If you are migrating from `gatsby-transformer-remark` to `gatsby-plugin-mdx`, be aware of breaking changes introduced in v4 of the MDX plugin. According to the source code in [`packages/gatsby-plugin-mdx/src/gatsby-node.ts`](https://github.com/gatsbyjs/gatsby/blob/main/packages/gatsby-plugin-mdx/src/gatsby-node.ts), version 4 was rewritten to use MDX v2 and removed legacy options including `defaultLayouts`, `mediaTypes`, and `jsFrontmatterEngine`.

To migrate successfully:

1. Replace `defaultLayouts` with shadowing or explicit component imports in MDX files.
2. Move remark plugins from `gatsby-transformer-remark` configuration to the `gatsbyRemarkPlugins` or `mdxOptions.remarkPlugins` arrays.
3. Update GraphQL queries to use `Mdx` instead of `MarkdownRemark` and replace `html` references with `body` or component rendering logic.

## Summary

- **`gatsby-transformer-remark`** converts pure Markdown files into `MarkdownRemark` nodes with pre-rendered `html`, ideal for static blogs and RSS feeds.
- **`gatsby-plugin-mdx`** compiles MDX files into `Mdx` nodes with JSX support, enabling React component embedding for interactive content.
- Both plugins can coexist in the same project when content is separated into different source directories.
- Choose `gatsby-transformer-remark` for performance-critical static content and `gatsby-plugin-mdx` for component-rich, interactive documentation or marketing pages.

## Frequently Asked Questions

### Can I use both gatsby-transformer-remark and gatsby-plugin-mdx in the same Gatsby site?

Yes, both plugins can coexist in the same project. Configure `gatsby-source-filesystem` to source different directories for each plugin, ensuring that `gatsby-transformer-remark` processes pure Markdown files while `gatsby-plugin-mdx` handles `.mdx` files. This setup allows you to maintain a traditional blog with the remark transformer while using MDX for interactive documentation pages.

### Why did my GraphQL queries break after switching from gatsby-transformer-remark to gatsby-plugin-mdx?

The plugins expose different GraphQL node types. `gatsby-transformer-remark` creates `MarkdownRemark` nodes with an `html` field containing pre-rendered HTML strings. `gatsby-plugin-mdx` creates `Mdx` nodes where content is accessed via `body` (raw MDX source) or rendered as React `children` in page templates. Update your queries to target `allMdx` or `mdx` instead of `allMarkdownRemark`, and replace `html` references with `body` or component rendering logic.

### Does gatsby-plugin-mdx support all gatsby-remark-plugins?

Yes, `gatsby-plugin-mdx` supports most `gatsby-remark-*` plugins through the `gatsbyRemarkPlugins` configuration option. These plugins run during the remark phase of MDX processing. However, you must explicitly configure them in the `gatsby-plugin-mdx` options rather than in a separate transformer configuration. Note that some remark plugins may behave differently with MDX v2's syntax tree, so test compatibility when migrating from `gatsby-transformer-remark`.

### Which plugin offers better build performance for large content sites?

For sites with thousands of static Markdown files and no interactive components, `gatsby-transformer-remark` typically offers faster build times because it generates static HTML strings without the overhead of JSX compilation and React component wrapping. `gatsby-plugin-mdx` incurs additional processing costs to compile MDX into executable JavaScript, which becomes worthwhile only when you need the interactivity and component composition that MDX provides. For pure content sites, the remark transformer remains the performance-optimal choice.