We use cookies to improve your experience.

Mobile Reality logoMobile Reality logo

JSON Render vs MDMA: Why the MD Format Might Be the Better Choice for Generative UI

MDMA vs JSON render

Introduction

MR Agent Conversation
MR Agent Conversation

Generative UI has a new shape: instead of plain text, an LLM returns a structured description of an interface and your app renders it natively. Two open frameworks take that idea seriously but make opposite bets on the format. json-render bets on JSON - its tagline is "AI → json-render → UI." MDMA (Markdown Document with Mounted Applications) bets on Markdown: the model writes an ordinary document with interactive blocks mounted inline. This is not "structured UI vs. freeform text" - both frameworks constrain the model and render into React. It is a disagreement about which structured format a model should author, and the interesting question is when the MD format is the better choice.

The two bets

Both frameworks accept that AI responses should be actionable, not prose. Both constrain what the model can produce - json-render to a developer-defined catalog, MDMA to fixed component schemas. And both treat reliable, renderable output as the central engineering problem. The disagreement is only the surface the model writes onto.

From global variables to model-authored UI

JSON as a user interface format is not new. Long before LLMs, declarative JSON UI systems described a page as a tree of element types - containers like stack_panel, labels, buttons, and similar controls, documented largely in community wikis - and threaded shared values through global variables, all in hand-authored ui files maintained by developers. json-render inherits that lineage but points it at a model: instead of a person writing the tree, the AI generates it under guardrails. MDMA inherits a different lineage - the document - and asks the model to write that instead.

What json-render is

json-render is a generative UI framework that produces dynamic, personalized UIs from prompts "without sacrificing reliability." That reliability comes from guardrails: the AI may only use components and actions you have declared in a catalog, so it cannot drift outside what your app already knows how to render.

The spec format: root and elements

A json-render document is a flat tree - a root id plus an elements map of id to type, props, and children:

json
{
  "root": "card-1",
  "elements": {
    "card-1": { "type": "Card", "props": { "title": "Revenue" }, "children": ["m1"] },
    "m1": { "type": "Metric", "props": { "label": "Revenue", "value": "$48,200" } }
  }
}

The root points at the entry element; every node references its children by id. Inside each element, props is a set of property name and property value pairs that configure the component. The catalog - typed with Zod - acts as a template for everything the model may emit, so it cannot invent a component or pass a prop that does not exist.

Catalog, streaming, and code export

Output streams as JSONL patches into the tree, so the UI fills in progressively as the model responds. Data bindings connect props to runtime state through $state paths, with $item and $index for array iteration and two-way bindings for inputs. A finished UI can be exported as standalone React with no runtime dependency, and because the tree is id-addressable, programmatic modifications after generation are clean. It targets React on the web and React Native on mobile.

What MDMA is

MDMA treats a Markdown file as an application. Standard Markdown - headings, paragraphs, lists, images, links - renders as it always has. The interactive parts live inside fenced mdma code blocks written in flat YAML, so a regular document becomes an interactive screen.

Forms, buttons, and the built-in components

MDMA ships nine component types - form, button, tasklist, table, chart, callout, approval-gate, webhook, and thinking - each rendered out of the box by @mobile-reality/mdma-renderer-react, with ordinary Markdown flowing inline between them. There is no enclosing tree and no id map; components render where they appear.

The same screen, two formats

A settings panel in json-render is a normalized, id-referenced tree:

json
{
  "root": "panel",
  "elements": {
    "panel": { "type": "Card", "props": { "title": "Settings" }, "children": ["n", "v"] },
    "n": { "type": "Switch", "props": { "label": "Notifications", "checked": { "$state": "prefs.notify" } } },
    "v": { "type": "Slider", "props": { "label": "Volume", "min": 0, "max": 100, "value": { "$state": "prefs.vol" } } }
  }
}

The same screen in MDMA is two flat blocks in document order:

`markdown
type: callout
id: settings-intro
variant: info
text: "Adjust your preferences below."
type: form
id: settings-form
fields:
name: notifications
type: checkbox
    label: "Enable notifications"
name: volume
type: number
    label: "Volume"
    min: 0
    max: 100

There is no root, no id map, and no children arrays to keep in sync - layout is simply document order, the way headings and paragraphs already flow. The core bet of the MD format: for generative UI, a linear document of small flat blocks is easier to author correctly than a single normalized object graph.

The authoring problem

Judge both frameworks on the case they are built for: the model is the author. The relevant question is not which format is cleaner data - JSON wins that easily - but which a model emits correctly more often, especially in long conversations.

Why a JSON tree is hard to emit

A model producing a json-render tree must hold several invariants token by token: balanced braces, no trailing commas, quoted keys, root naming a real element, and the hard one - every id in a children array must exist in elements. Add a child reference but forget the element and the tree breaks even though the JSON parses. Constrained generation keeps this in line for short, single-shot outputs; the referential drift shows up in long, multi-turn dialogues where the element map keeps growing.

Why Markdown plays to a model's strengths

Models have seen billions of Markdown documents in training; writing headings and fenced code blocks is the most natural thing they do. MDMA's components are short, flat YAML - no brace matching, no cross-id bookkeeping, most values unquoted - because order is the structure. The payoff shows up in data: MDMA's eval matrix places flagship models from OpenAI, Anthropic, Google, and xAI at or near 100% across one-shot, custom-prompt, conversation, and multi-step flow scenarios.

Validation and auto-fix

A static validator runs seventeen lint rules and auto-fixes six of them - auto-quoting colon values, stripping stray --- separators, splitting multi-component blocks. Even complex forms (multi-field, conditional, PII-flagged) are described as one flat block and validated against a Zod schema. The philosophies differ: json-render prevents bad output by constraining generation up front; MDMA validates too, but because its surface is forgiving text, it can repair near-misses rather than only reject them.

Bindings, state, and data flow

json-render binds with explicit typed markers ($state, $item, $index) nested inside the tree. MDMA uses one inline syntax, {{path}}; the runtime builds a dependency graph from these expressions and re-renders only what changed, and the validator lints every binding for empty braces, stray whitespace, and single-brace typos. Both are legible in different ways - json-render's bindings are explicit and strongly typed, MDMA's are readable in the context of the surrounding prose.

Rendering to React

A json-render app composes a StateProvider, a VisibilityProvider, and a Renderer that walks the tree from root, resolves each type against a registry of platform components, applies props, and renders children by id - that registry is what lets one spec target both React and React Native. MDMA splits the work the same way: a parser turns Markdown into an AST and validates each block's YAML, a headless runtime manages state and bindings, and the React renderer maps each type to a component. Crucially, the spec describes intent - type: form, required: true - while the renderer owns presentation, so a rule like which files a field accepts lives in the renderer, not the model's output. Both frameworks decouple presentation this way: MDMA's chart renders as a plain table by default and you pass a custom component under customizations.components.chart to swap in real charts, while json-render does the equivalent through its registry - either way you change how a type looks without touching what the model emits.

A side-by-side scorecard

Dimension / json-render (JSON) / MDMA (MD)
Dimensionjson-render (JSON)MDMA (MD)
Spec shaperoot + elements treeLinear document of blocks
AI authoringMust keep tree consistentPlays to model strengths
ErrorsGuardrails rejectValidator + auto-fix repairs
PR reviewid-referenced graphReads as a document
StreamingFirst-class JSONL patchesRe-parse on update
Code exportEject to standalone ReactRenders via runtime
TargetsReact + React NativeReact (custom renderers) + React Native (TBD)

Where json-render wins

If you need an addressable tree - patch nodes by id, stream partial updates into a live UI, or make programmatic modifications after generation - JSON is the right data structure. json-render also wins when you want to eject to standalone code, or when generation must be constrained to an exact catalog. For those properties, it is purpose-built.

Where the MD format wins

For conversational, document-shaped UIs - intake flows, checklists, reports with an approve button, mostly-prose-with-a-form-at-the-end - Markdown matches the domain naturally. With no referential graph to maintain, a whole class of model errors simply cannot happen, pushing reliability up exactly where JSON trees get fragile: deep in long dialogues. And because an MDMA file is text that reads like prose, it fits the tools developers already use - you commit it to GitHub and review the diff in a pull request like any other code, without mentally reassembling a JSON tree.

Common objections

"Markdown is loose; you lose schema safety"

You don't. Every component validates against a Zod schema in the spec package, with fuzzy suggestions - "frm" prompts did you mean "form"? - so the surface is forgiving while the schema underneath is as strict as json-render's catalog.

"Isn't YAML fiddly?"

YAML has footguns, but MDMA's blocks are shallow - a type, a few props, maybe a list of fields - so the deep indentation that makes YAML painful rarely appears, and the validator targets the mistakes models actually make.

"What about addressable, streamable trees?"

This is the real boundary, and json-render is genuinely better at it. If you must patch nodes by id, stream partial updates into a live tree, or eject to code, choose JSON. MDMA's linear document put focus on authoring reliability, interactivity, speed, and costs.

A realistic flow

Pick a model-tuned prompt variant, optionally layer a domain prompt, and send it as the system prompt:

typescript
import { buildSystemPrompt, getAuthorPromptVariant } from '@mobile-reality/mdma-prompt-pack';
const { prompt: authorPrompt } = getAuthorPromptVariant('google/gemini-2.5-pro');
const systemPrompt = buildSystemPrompt({ authorPrompt });

The model replies with Markdown containing mdma blocks. Parse it to an AST, create a store, and render with <MdmaDocument ast={ast} store={store} />. User input dispatches actions, bindings update, dependent components re-render - every step in a format a human can read.

Tooling

A CLI prompt builder lets you visually pick components and generate a tailored prompt; a validator runs the rules in CI and reports how many issues it fixed via result.fixCount; and an MCP server exists to help an agent integrate by exposing the spec, prompts, and docs as callable tools.

Choosing between them

Ask what shape your UI is, how long your conversations run, and whether you need to eject to code. Addressable, streamed, code-exportable UIs favor json-render. Document-shaped flows that users interact with favor the MD format.

The bigger picture

json-render and MDMA are two credible answers to the same question, and the choice is about what you hand the model. A format built for machines to address and exchange data (a JSON tree) is excellent when you need those properties. A format built for a machine to author and a human to read (a Markdown document) is excellent when reliability-under-generation and reviewability matter most. For the growing class of UIs where the AI generates the screen, the user interacts in a conversation, and the team reviews the result like code - the MD format is, more often than not, the better choice.

Resources

  • json-render.dev - the JSON-based framework compared here.
  • MDMA - live demo, docs, GitHub, component catalog, prompt pack, and validator.

MDMA is built and maintained by Mobile Reality. Markdown in, interactive applications out.

Frequently Asked Questions

Who is an AI agent developer?

An AI agent developer is a software engineer who builds autonomous AI agents — systems that plan, use tools, and execute real tasks against APIs and data, not just chatbots. At Mobile Reality, our AI agent developers combine LLM expertise (OpenAI, Anthropic Claude) with production engineering: orchestration, observability, and guardrails.

Who is developing AI agents at Mobile Reality?

A dedicated team of AI agent developers and AI experts. Our developers work fluently across LangGraph, LangChain, MCP servers, and OpenRouter for multi-model access, applying prompt engineering and evaluation to every AI project. The live agent on this page is built and run by the same team.

Which AI agent framework is best for developers?

There is no single best AI agent framework — it depends on the workflow. For stateful, multi-step orchestration we use LangGraph; for model and API integration, LangChain; for tool access to your stack, MCP servers; and OpenRouter to route across OpenAI, Claude, and open-source models. Our AI agent developers pick the agent architecture that fits your tasks and budget.

What does the AI agent development process look like?

Our AI agent development process follows a clear step guide: scope the tasks and tools, design the agent architecture and model roles, implement orchestration through OpenRouter with guardrails and observability, then ship and iterate. We treat building agents as real software engineering — with evaluation harnesses, cost caps, and regression tests.

How much does it cost to hire AI agent developers?

Cost depends on scope, integrations, and the models involved. A well-scoped custom AI agent project typically lands 40-70% cheaper at scale than per-resolution agent SaaS, because it runs on your own keys and is tuned for your workflows. Book a consultation and we'll estimate your AI project against concrete tasks and tools.

Discover more on AI-based applications and genAI enhancements

Artificial intelligence is revolutionizing how applications are built, enhancing user experiences, and driving business innovation. At Mobile Reality, we explore the latest advancements in AI-based applications and generative AI enhancements to keep you informed. Check out our in-depth articles covering key trends, development strategies, and real-world use cases:

Our insights are designed to help you navigate the complexities of AI-driven development, whether integrating AI into existing applications or building cutting-edge AI-powered solutions from scratch. Stay ahead of the curve with our expert analysis and practical guidance. If you need personalized advice on leveraging AI for your business, reach out to our team — we’re here to support your journey into the future of AI-driven innovation.

Did you like the article?Find out how we can help you.

Matt Sadowski

CEO of Mobile Reality

CEO of Mobile Reality

Related articles

Explore how conversational AI with MDMA enables real-time interactive responses like forms and buttons, boosting customer action completion by integrating dialogue and workflows seamlessly.

09.06.2026

Conversational AI with Interactivity

Explore how conversational AI with MDMA enables real-time interactive responses like forms and buttons, boosting customer action completion by integrating dialogue and workflows seamlessly.

Read full article

Boost sales leads by 30% with MDMA AI forms—dynamic, context-aware chat forms that capture cleaner data and reduce funnel drop-offs seamlessly.

03.06.2026

MDMA AI Sales Assistant 2026: Boost Leads 30%, Own Your Forms

Boost sales leads by 30% with MDMA AI forms—dynamic, context-aware chat forms that capture cleaner data and reduce funnel drop-offs seamlessly.

Read full article

A comment on why MD format beats HTML for generative UI. Covers a2ui, generative apps, CopilotKit patterns, and why declarative generative formats work across platforms.

22.05.2026

Why MD Format Might Wins for Generative UI

A comment on why MD format beats HTML for generative UI. Covers a2ui, generative apps, CopilotKit patterns, and why declarative generative formats work across platforms.

Read full article