You’re writing MDX and your build suddenly crashes: [@mdx-js/rollup] Could not parse expression with acorn. Followed by Unexpected content after expression. Frustrating, right?
The culprit: curly braces ({}) or LaTeX math blocks ($$) that the MDX compiler mistakes for JavaScript expressions. Here’s why that happens and how to fix it — fast.
- The Cause: The MDX parser treats curly braces (
{}) outside code blocks as JSX JavaScript expressions. When the compiler evaluates math formulas or regular prose containing braces, it fails to parse them as executable code. - Immediate Fix: Replace literal curly braces with standard HTML character entities (
{and}) in your text. - Scalable Fix: Configure a custom Rehype/Remark markdown plugin to automatically sanitize and escape mathematical blocks at build-time.
Why Braces Crash the Build
MDX is markdown that can also run JSX components. So the compiler treats everything inside {} as JavaScript:
MDX Compilation Logic:
"Prose text { literal } prose" --> [MDX Parser] --> [Acorn AST Compiler] --> Treats "{ literal }" as JavaScript!
|
Acorn Parser Fails here! Write something like CSS variables use the var(--name) syntax and the compiler feeds --name into Acorn (a JavaScript parser). Spoiler: --name is not valid JS. Crash.
Step 1: Escape Braces With HTML Entities
Fastest fix: replace { and } with HTML entities. The HTML parser resolves them after MDX compilation, so Acorn never sees them.
| Raw Character | MDX Entity Representation |
| :--- | :--- |
| { (Open Brace) | { |
| } (Close Brace) | } |
What crashes:
To define a CSS variable, declare it inside the root selector:
:root {
--theme-color: #3b82f6;
} Acorn sees { and tries to parse --theme-color: #3b82f6; as JavaScript. It fails. Build breaks.
What works:
To define a CSS variable, declare it inside the root selector:
:root {
--theme-color: #3b82f6;
} The HTML entities { and } get resolved into { and } after MDX compilation. Acorn never sees them. Build stays green.
Step 2: Handle Formulas and Special Notation
LaTeX blocks with braces will crash the compiler if they aren’t wrapped or escaped. Here’s what’s safe and what isn’t.
Fenced Code Blocks — Safe
MDX ignores everything inside standard code blocks. They get parsed as raw strings, so braces inside them never reach Acorn:
// Totally safe in MDX
const user = { name: "Darsh" }; Need to show a YAML config or a CI/CD pipeline snippet? Wrap it in a fenced code block. You’re good.
Double-Dollar Math Blocks — Crash Risk
$$ math blocks look like this in LaTeX:
$$ \text{Profit} = (\text{Visitors} \times \text{Yield}) - \text{Cost} $$ If the content inside has curly braces, Acorn will try to parse it as JavaScript and fail.
The workaround: skip LaTeX and write your equations as plain markdown instead:
- Net Profit = (Visitors × Average Earnings Per Visitor) − Total Traffic Cost
- Net Profit = (10,000 × $0.06) − $500.00 = $100.00
Same information, zero curly braces, zero crashes.
Step 3: Auto-Escape With Compiler Plugins
If you have hundreds of posts with math formulas, escaping every brace by hand gets old fast. Better approach: add remark-math and rehype-katex to your compiler pipeline. These plugins parse math blocks into safe HTML nodes before Acorn ever touches them.
Install:
pnpm add remark-math rehype-katex Then register them in your Astro config:
// astro.config.mjs
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
import remarkMath from 'remark-math';
import rehypeKatex from 'rehype-katex';
export default defineConfig({
integrations: [
mdx({
remarkPlugins: [remarkMath],
rehypePlugins: [rehypeKatex]
})
]
}); Once that’s in place, you can write standard LaTeX with braces directly in your MDX. No crashes. No manual escaping. For a related exploration of rendering visual elements dynamically in modern web contexts, see my previous hands-on guide on Exporting HTML Canvas to Images using Native JavaScript.
Frequently Asked Questions
Can I escape curly braces using backslashes?
No. In regular markdown, \{ works as an escape. In MDX, the backslash passes through literally — Acorn still sees the raw brace. You must use { and } instead.
Why do some curly braces work without escaping?
If the content inside {} happens to be valid JavaScript (like an empty object {}), Acorn compiles it fine. But most prose isn’t valid JS, so it crashes. This isn’t a bug you can rely on — use entities.
Does this error affect Next.js pages?
Yes. The MDX spec is the same across Astro, Next.js, and Gatsby. If you’re using @mdx-js/loader or @mdx-js/rollup, you’ll hit the same Acorn crashes with unescaped braces.
Related Articles
Deepen your understanding with these curated continuations.
Best Ad Networks as Google Ads Alternatives in 2026: A Publisher's Guide
Compare the top 9 Google AdSense alternatives for 2026. Detailed breakdown of Mediavine, Raptive, Ezoic, Monumetric, and more. Traffic requirements, CPMs, and which network fits your niche.
Showcasing Premium MDX Features
A deep dive into the interactive components and enhanced reading experience of MeshWorld.
Buying Traffic vs. Earning From Ads: Publisher vs. Advertiser Guide
Understand the distinct roles of publishers and advertisers. Compare the economics of buying traffic (arbitrage) vs. earning from display ads in 2026.