After two and a half years of waiting for development, MDX v2 has finally been released. MDX v2 packs in some much-needed improvements to MDX v1’s capabilities in areas such as performance and syntax, and adds features like support for JavaScript expressions and more JSX runtimes.
In this article, we will explore some of the amazing improvements highlighted in the MDX v2 release notes, including:
Enjoy!
The newly improved MDX syntax makes it easier to use MDX in JSX, as compared to the first version. According to the MDX team’s release post,
We’ve spent a lot of time thinking and trying out different ways to improve the format. Originally, the format was very close to how Markdown, and HTML in Markdown, works. We found that the old behavior often yielded unexpected results. In version 2, we shift the format a little bit closer to how JS(X) works.
In the old format, MDX syntax was converted to its relative Markdown format, like so:
<div>*italicize*</div>
converted to <div>*italicize*</div>
<div># header one</div>
converted to <div># header one</div>
But this caused a wide array of parsing issues. Using the new syntax, MDX code will be converted directly to its equivalent JSX format:
<div>*italicize*</div>
becomes <div><em>italicize</em></div>
<div># header one</div>
becomes <div><h1>header one</h1></div>
This update promises to address the parsing issues experienced in the MDX v1 syntax. Follow this link to learn more about the MDX v2 syntax.
MDX v2 ships with support for adding expressions, like JavaScript expressions, to MDX code. The expressions can be added anywhere in an MDX document inside curly braces, and do not need to be restricted to certain areas of the document.
Now, you can do amazing stuff like perform arithmetic operations directly in your MDX code. For example, this code:
# Quick maths -> { (2+2) * Math.PI}
produces this output:
Quick maths -> 12.566370614359172
The expression’s curly braces can also be empty or contain a comment.
{/* This is a lovely comment! */}
To learn more about MDX expressions, visit this link.
MDX v2 has added support for more JavaScript runtimes and bundlers. The v1 version of MDX worked mainly with Babel, webpack, and React, and was not able to easily be used with other tools.
This has been changed in the v2 release. Babel, webpack, and React are now optional, and MDX can now be used with:
Visit the MDX migration page to learn more.
MDX v2 has completely switched to support only ECMAScript modules (ESM). While MDX v1 offers support for ESM, v2 will only work with tools that support ESM. Hence, imports like those below won’t work MDX v2.
const data = require('./data')
import { foo } from 'foo/lib/main'
You have to change it to ESM JavaScript instead.
import data from './data.js'
import { foo } from 'foo/lib/main.js'
Learn more about MDX v2 ESM support here.
The entire MDX documentation has been rewritten from top to bottom to provide a better experience for folks trying to tinker with MDX v2. All inconsistent and duplicated content has been removed from the documentation website, too.
The documentation website was also rebuilt with MDX and provides a more optimized experience and performance. According to the MDX team, the new documentation website scores well in all performance and accessibility tests compared to the previous version.
The entire MDX architecture has been rewritten to improve performance and capability in the new version. The new architecture has:
But the most exciting feature is the improved abstract syntax trees (AST). The new AST describes the MDX v2 syntax in more detail, which will improve the ecosystem around MDX by allowing plugins to enhance MDX in new ways, and also help MDX solve edge cases that would have previously caused a crash.
The MDX team claims that the improved architecture speeds compiling time by 25 percent over the former version, generating code is 100 percent faster, and bundle sizes are 250 percent smaller than those written using MDX v1.
You can learn more about the improved architecture in the release notes.
The improved MDX architecture also comes with TypeScript support. According to the MDX team,
All @mdx-js/* packages are now fully typed with TypeScript through JSDoc comments. That means our APIs are exposed as TypeScript types but also that our projects are type-safe internally.
To add TypeScript support to your MDX document, install @types/mdx.
npm install @types/mdx
TypeScript should automatically pick up MDX documents after the installation.
Before migrating your app to MDX v2, make sure you are using the latest version React, Preact, or Vue 3. Also, note that tools without ESM support won’t work in MDX v2, you can learn more about MDX v2 ESM support here.
You can update your React version with the following command.
npm install --save react@latest
Then, install (@mdx-js/react) with the following command.
npm install @mdx-js/react
To add MDX v2 to Vue CLI, first, update your Vue apps with the following command.
npm update -g @vue/cli
The install (@mdx-js/vue) with the following command.
npm install @mdx-js/vue
To add MDX v2 to a Preact app, first, install the latest version of Preact.
npm install preact
Then install (@mdx-js/preact) with the following command.
npm install @mdx-js/preact
Visit the MDX migration guide for more instructions on how to migrate from MDX v1 to MDX v2.
You will likely get errors from your MDX files after upgrading to the new version because of the new syntax. Study the error messages carefully to know what errors you are getting and how to fix the errors. Here are some commons ones:
Could not parse import/exports with acorn: $error
— This occurs when you use an invalid import
or export
statementUnexpected end of file in expression, expected a corresponding closing brace for `{`: $error
— This occurs when you have an opening curly brace without a closing curly braceCould not parse expression with acorn: $error
— This occurs when the expression inside a curly brace is invalidCould not parse expression with acorn: Unexpected content after expression
— This occurs when there is too much expression in a curly braceSee MDX v2 Troubleshooting guide for more errors and how to solve them.
If you are having problems integrating MDX v2 with a specific tool, this is most likely due to MDX v2 ESM support. MDX v2 only works with tools that support ESM, unlike MDX v1. You can learn more about MDX v2 ESM support here.
In this article, we talked about the newly released MDX v2. We talked about the improvements to architecture and syntax, their possible breaking changes, and how to migrate to the new version in React, Vue, and Preact apps.
The newly released MDX v2 brings some much-needed improvements to the MDX language. The improved syntax should make MDX more convenient to use, due to the reduced parsing problems. The added support for more JSX runtimes should also increase its adoption by more frontend frameworks.
More improvements are still coming — right now, we know that support for JavaScript variable declaration with let/const/var
is expected to ship in v2.1, and MDX plugins are expected to ship in v2.2.
For further information, you can visit the MDX releases notes on GitHub.
Install LogRocket via npm or script tag. LogRocket.init()
must be called client-side, not
server-side
$ npm i --save logrocket // Code: import LogRocket from 'logrocket'; LogRocket.init('app/id');
// Add to your HTML: <script src="https://cdn.lr-ingest.com/LogRocket.min.js"></script> <script>window.LogRocket && window.LogRocket.init('app/id');</script>
Would you be interested in joining LogRocket's developer community?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowIt’s easy for devs to default to JavaScript to fix every problem. Let’s use the RoLP to find simpler alternatives with HTML and CSS.
Learn how to manage memory leaks in Rust, avoid unsafe behavior, and use tools like weak references to ensure efficient programs.
Bypass anti-bot measures in Node.js with curl-impersonate. Learn how it mimics browsers to overcome bot detection for web scraping.
Handle frontend data discrepancies with eventual consistency using WebSockets, Docker Compose, and practical code examples.