Bridging two JSX runtimes: How we solved Astro's React children problem
March 10, 2026
Kyle Finken
Engineering
Share this article

When we built Mintlify's Astro integration, compound React components silently broke on hydration. The culprit: two JSX runtimes fighting over the same component tree. Here's how we fixed it without changing the Mintlify docs experience.
We built Mintlify so teams could ship great developer docs without having to think about infrastructure. For most, our model works extremely well.
But over the past year, a different pattern started to show up in conversations with some of our largest customers. Some wanted to embed docs directly inside their developer console. Others wanted a fully custom UI with their own layouts, and design system. Across all of them, the request was basically the same: keep Mintlify's content engine and AI features, but let us own the frontend.
So we built an Astro integration.
What we built
The goal was straightforward, let teams own their frontend while Mintlify continues to handle the content layer underneath.
With the integration, Mintlify content syncs into Astro content collections at build time. Teams can build their docs experience however they want in Astro, while still using Mintlify for content management, search, and AI-powered features.
The content pipeline came together quickly. The harder problem was rendering our React component library correctly inside Astro's MDX pipeline.
The problem
Any compound component broke silently on hydration.
<Tabs>, <Accordion>, and <CodeGroup> would all render the parent, but the children would disappear.
Simple components like badges or callouts were fine. But anything compound, where the parent needs to understand and manage its children, failed.
Why this breaks in Astro
Astro compiles MDX using its own JSX runtime. That is part of what makes it fast. You get static HTML at build time, and no framework gets shipped to the client unless you explicitly opt into hydration.
When you add client:load to a React component, Astro hydrates that component on the client. The issue is what happens to its children.
By the time React receives a <Tabs> component, Astro has already compiled its <Tab> children into Astro nodes. They are no longer real React elements, which means React cannot inspect them, pass props through them, or re-render them correctly when state changes.
That is fine for static content. It is a dealbreaker for components like <Tabs>, where the parent needs real React children to drive interactivity.
Astro does have an experimentalReactChildren flag that preserves React elements across that boundary. But it only works in .astro files, not in MDX. Since our entire content pipeline runs through MDX, that path was closed to us.
The solution
If we could not control how Astro compiled those children, we needed to make sure Astro never saw them in the first place.
Our integration hooks into astro:config:setup, which runs before Astro's MDX compiler. At that point, we parse every page into a markdown AST and walk the tree looking for compound components.
When we find one, we extract the entire subtree from the raw MDX source. The parent, and all of its children together.
We then compile that extracted MDX independently. That gives us a self-contained React module where both the parent and children stay entirely inside React's JSX runtime. We write that out to a JSX file.
Back in the original AST, we replace the compound component with a childless wrapper that imports the extracted module and hydrates it with client:load.
So instead of asking Astro and React to share ownership of the same component tree, we give the whole interactive subtree to React and let Astro handle the rest.
What this unlocks
Teams can now own their entire frontend stack while Mintlify continues to handle the content layer underneath. Page content, navigation, snippets, and static assets all sync at build time. Search and AI features carry through.
None of this affects docs authoring. Use the same <Tabs>, <Accordion>, and other components exactly as you would in Mintlify today. The extraction happens before Astro ever sees the page.
The integration is generally available. If you've hit the same wall with compound React components in Astro MDX, the pipeline is open sourced. To build a fully custom docs frontend on top of Mintlify's content engine, check out the integration, start from the starter template, or reach out to our team.
More blog posts to read
What three years of watching AI in production taught us
Learn what three years of watching AI in production taught us about the knowledge layer and why that realization led us to join Mintlify.
March 11, 2026Justin Torre
Engineering Manager
Cole Gottdank
GTM Manager

AI agents are shipping faster than anyone can document
AI agents are shipping faster than anyone can document. Workflows closes the gap by automatically updating your docs when your product changes.
March 9, 2026Hahnbee Lee
Co-Founder
Kyle Finken
Engineering