Gatsby Transformer Remark vs Plugin MDX: Choosing the Right Markdown Engine
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 and 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 |
Auto-creates pages for .mdx files in src/pages |
How gatsby-transformer-remark Works
In 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 with remark-specific options:
// 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:
{
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, 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):
// 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:
{
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:
// 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
htmlfield 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
remarkPluginsandrehypePluginsviamdxOptions.
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, version 4 was rewritten to use MDX v2 and removed legacy options including defaultLayouts, mediaTypes, and jsFrontmatterEngine.
To migrate successfully:
- Replace
defaultLayoutswith shadowing or explicit component imports in MDX files. - Move remark plugins from
gatsby-transformer-remarkconfiguration to thegatsbyRemarkPluginsormdxOptions.remarkPluginsarrays. - Update GraphQL queries to use
Mdxinstead ofMarkdownRemarkand replacehtmlreferences withbodyor component rendering logic.
Summary
gatsby-transformer-remarkconverts pure Markdown files intoMarkdownRemarknodes with pre-renderedhtml, ideal for static blogs and RSS feeds.gatsby-plugin-mdxcompiles MDX files intoMdxnodes 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-remarkfor performance-critical static content andgatsby-plugin-mdxfor 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.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →