The best React rich text editor outputs React, not JSON
Use a React rich text editor that writes MDX, and content comes out as renderable source instead of a document format you still have to parse. Draftbase ships a block-based MDX editor built around exactly that idea — write a block, publish it, and it's already a React-renderable string, with no export step in between.
Simplified preview — the real editor renders full MDX.
What is a rich text editor for React, and why MDX changes the tradeoffs
A React rich text editor is a component that lets a writer format text — headings, bold, links, embedded blocks — inside a React app. Most popular options, including Slate, TipTap, Lexical, and Draft.js, store that formatting as a proprietary JSON document. The editor's own internal model, not standard markup.
Ask "what's the best React rich text editor" and most answers name a library. That's the wrong first question. The better question is what format the content ends up in, because the format decides how much work is left after the editor ships. A "react wysiwyg editor" and a "text editor for React" are the same underlying tool — the name changes, the format tradeoff doesn't.
That JSON document is not directly renderable. Every team using one of these libraries has to write a serializer that walks the document tree and turns it into HTML or React elements. Change the schema, and the serializer has to change too. Add a new block type — a callout, an embedded video, a code sandbox — and the serializer needs a new branch to handle it. The editor's flexibility becomes the renderer's maintenance burden.
This isn't a knock on those libraries. Slate, TipTap, and Lexical are genuinely good at what they're built for — structured, extensible editing surfaces. The tradeoff is scope: they solve editing, and leave rendering as a separate, ongoing project for whoever consumes the output.
MDX is a different kind of output entirely. It's Markdown plus JSX, which means a React wysiwyg editor built on MDX produces content that is already valid, renderable React source — not an intermediate format waiting on a custom renderer. A heading in MDX is a Markdown heading. A custom block is a JSX component, imported and used the same way any other component in the app is used.
This is also why an MDX-based editor travels well. The same content string renders the same way in a blog, a docs site, or a marketing page, because it isn't tied to one library's internal document model. Move the content to a different React project, and it still renders — no migration script required.
Consider a simple example: a writer wants to embed a pricing table inside a blog post. In a JSON-document editor, that means defining a new node type, teaching the editor's UI to insert it, and teaching the serializer to turn it back into a component. In MDX, it means writing <PricingTable plan="pro" /> inside the text — a component that already exists in the app, used the way any JSX component is used.
This doesn't mean the editor has no learning curve. A writer still needs to know Markdown basics — headings, bold, blockquotes — the same way they would for any React wysiwyg editor. What's removed is the second learning curve: the frontend team never has to learn a proprietary document schema just to display what the writer typed.
How Draftbase's MDX editor works
The MDX editor for React is built around four pieces that fit together end to end, from typing a heading to rendering that heading in an app. Each piece is small on its own, but the combination is what removes the renderer-building step.
Block-based editing
Content is edited and selected as discrete blocks — headings, callouts, paragraphs — instead of one long text stream, which keeps structure visible while writing and makes each block individually selectable and reorderable.
Typed field validation
Every template field carries its own validation rules — required, length, pattern — enforced on write, so a bad entry never reaches the delivery API or a live page.
Drop-in editor
Writers get an intuitive editor out of the box — no setup, no separate CMS to host.
Renders via <MDXContent>
Stored MDX renders with @draftbase/renderer's MDXContent component — no custom parser to write or maintain.
Custom React components used inside content are registered separately, through the MDX components screen. Each component is defined once, with a typed set of props — string, number, boolean. A writer then drops a named component into a block the same way they'd type a heading, and the field editor validates the props before the entry saves.
None of these four pieces require a separate build step. There's no compiler to configure, no plugin chain to assemble before content becomes usable. Write MDX in the editor, publish the entry, and it's ready for MDXContent to render.
A non-technical writer never sees any of this plumbing. They see blocks, a toolbar, and a save button. The typed schema and the component registry work in the background — the writer's job is still just writing, formatting, and dropping in the occasional component, not learning MDX syntax by hand.
Because templates and MDX components are both schema-defined, edits aren't limited to the editor UI either. The same schema an agent reads to make MCP-connected edits is the schema a human editor fills in by hand — one source of truth for what a valid entry looks like, whichever way it gets written.
Comparing React rich text editor approaches
Every approach to rich text in React lands somewhere on the same spectrum: how much of the renderer do you build yourself, and how much ships with the editor. The table below lines up the three common paths on the same four questions.
| Approach | Slate / TipTap / Lexical (bring your own) | Generic CMS rich text field | Draftbase MDX editor |
|---|---|---|---|
| Output format | Custom JSON schema | CMS-proprietary JSON | Plain MDX string |
| Renderer needed | You build one | You build one | Ships built-in via @draftbase/renderer |
| Embed custom React components | Only if you build that yourself | Rarely supported | Native — MDX is JSX |
| Setup cost | Library + schema + renderer, days of work | CMS account + custom parser | Drop-in editor, no separate hosting |
The pattern across all four rows is the same. Bring-your-own editors and generic CMS fields both push the rendering problem onto the frontend team, later, as a separate project. An MDX editor for React folds that cost into the editor itself, so it's paid once instead of on every project that reuses the content.
Common pitfalls with rich text in React
Teams under-estimate the renderer-maintenance cost of a JSON-document rich text format. The editor library is easy to install. The serializer that turns its output into React elements is the part that keeps needing updates as content needs grow. Every new block type a writer asks for is a new branch in that serializer, reviewed and shipped by an engineer, not the writer who needed it.
A common shortcut is rendering CMS rich text with dangerouslySetInnerHTML. That's both an XSS risk and a dead end for embedding real React components in content. Injected HTML has no concept of a React component boundary, so a "call out box" or an embedded chart ends up as static markup at best, or an injection vector at worst.
This shows up most often when a team migrates from a page-builder CMS. The old field stored HTML, the new field stores HTML too, and dangerouslySetInnerHTML looks like the fastest way to ship. It works for plain paragraphs. It breaks the moment content needs an interactive component, a chart, or anything with client-side state — none of that survives a round trip through raw HTML.
The fix is picking a format the frontend framework already understands — which is what an MDX editor for React gives you by default. There's no serializer standing between what a writer types and what a browser renders, and no raw HTML string getting parsed at render time.
A third, quieter pitfall: teams run two different rich text formats across surfaces — Markdown in the docs site, a CMS's proprietary format in the blog — and end up maintaining two renderers instead of one. Standardizing on MDX for both collapses that into a single format and a single renderer, since MDX is a superset of Markdown already.
Demand for rich, structured editing keeps growing
The global WYSIWYG editor software market is projected to grow from $236.09 million in 2026 to $416.33 million by 2035, a 6.4% CAGR. (Source) More teams adopting rich editing tools means more teams eventually hitting the renderer-maintenance problem a proprietary JSON format creates. Growth in the editor market doesn't shrink that problem — it just means more teams discover it later, after the editor is already wired into production.
Per Next.js's own MDX documentation, MDX files compile down to regular JSX at build or request time, with no separate runtime needed to interpret them. That's the technical reason an MDX-based editor doesn't need a bespoke rendering layer the way a JSON-document editor does — the compiler step already exists in the framework.
For a team evaluating a React rich text editor today, that's the practical takeaway. Ask what the editor outputs before asking what it can format. An editor that outputs MDX is handing off work the framework already knows how to do. An editor that outputs a custom document format is handing off a project.
Try the MDX editor for React
Write a block, embed a component, and render it with @draftbase/renderer in one sitting.
Frequently asked questions
What is the best rich text editor for React?
There's no single best option — it depends on what the output needs to become. Slate, TipTap, and Lexical are strong choices if you're willing to build a renderer for their JSON output. Draftbase's MDX editor skips that step: the output is already valid MDX your React app can render directly, so evaluating editors starts with the output format, not the feature list.
Does Draftbase support Markdown/GFM syntax like tables and strikethrough?
Yes. Draftbase content renders through next-mdx-remote with remark-gfm enabled, so GFM tables, strikethrough, and task lists work without extra configuration.
Can writers embed custom React components in content?
Yes — that's the core difference between MDX and plain Markdown. MDX allows JSX inline, so a writer can drop a custom component into a paragraph the same way they'd type a heading.
Do I need to write a custom renderer for MDX content?
No. Draftbase ships @draftbase/renderer, which exposes an <MDXContent> component that renders stored MDX strings directly. Per Next.js's own MDX documentation, MDX compiles to standard JSX, so no bespoke parser is required on top of it — the component handles fetching the entry and compiling its MDX field in one call.
Is an MDX editor harder to set up than a generic CMS rich text field?
No — it's less setup, not more. A generic CMS rich text field still requires a custom renderer for its JSON output. Draftbase's editor is drop-in and requires no separate CMS to host, and the template schema doubles as the validation layer for every field a writer fills in.