Docz.me just launched — 14 days free on any paid plan. See pricing

MDX Converter

Paste MDX, get PDF / DOCX / HTML. Components from a curated allowlist render statically across every format. No client JS, no surprises.

Docz Team · EngineeringPublished
255 / 512,000 bytes

MDX without the JS-execution risk

How to convert

Three steps. No signup, no email, no cloud locker.

  1. 1

    Paste or upload

    Drop your Markdown or MDX file into the editor, paste source directly, or click Upload to load a file from disk.

  2. 2

    Choose format and theme

    Pick PDF, DOCX (Word), or HTML as the output format. Optionally switch to Academic for a cover page or README/Blog for GitHub-style typography.

  3. 3

    Convert and download

    Click Convert & Download. The file streams back as a real binary — no signup, no email, no cloud locker. Your source is never stored.

Why this converter

Built for the docz.me invoicing app — released as a free standalone because the underlying pipeline turned out to be useful on its own.

  • Server-side rendering, real binaries

    Output is a real PDF, real DOCX, or self-contained HTML — not a screenshot or rebadged HTML. Selectable text, embedded fonts, proper page breaks.

  • GFM and MDX in the same pipeline

    Tables, task lists, footnotes, autolinks parse like GitHub. Switch to MDX input for Callout / CodeBlock / Tabs / Steps components — all rendered statically.

  • Three themes, one source

    Default for clean modern docs, Academic with cover page and numbered headings, README/Blog for GitHub typography. Switch and re-render — keep your source.

  • Privacy first

    Stateless serverless function. Source text is never logged or persisted. 500 KB cap enforced before parse so the worst case is a friendly error.

  • MDX without the JS-execution risk

    Parse-only path. JSX expressions, ESM imports, and unknown components are rejected by design. No code from your source ever runs server-side.

  • No signup, no email gate

    Free, anonymous, ungated. Built by docz.me — the invoicing app for freelancers — but the converter stands alone with no account requirement.

MDX is great for source files; running arbitrary user MDX through a public converter is not. This route never evaluates the compiled output. Instead the unified pipeline parses MDX into MDAST with `remark-mdx`, security plugins reject JSX expressions and unknown ESM imports, and renderers walk the tree to produce static HTML, PDF, and DOCX. The only code that ever runs is our own.

Seven components are baked into the v1 allowlist: Callout, Note, Warning for semantic info blocks; CodeBlock for fenced source separate from triple-backtick markdown; Tabs and Steps for structural content (linearised to stacked sections and numbered lists in PDF and DOCX); and Image for SSRF-guarded picture embeds. Anything outside that set renders as a styled fallback block — your reader sees that something was unhandled rather than blank space.

Why no JSX expressions? Because whitelisting them safely is a moving target. `eval-estree-expression` and similar libraries are fragile, and accidental scope leaks have caused real-world incidents. The cleaner UX boundary is a hard reject, with a clear error message pointing at the offending line. Your prose stays expressive, your output stays static, and your visitor's tab doesn't run anything they didn't write.

Frequently asked

Why are JSX expressions like {1+1} rejected?

Because the evaluator surface area is too risky to whitelist. The converter rejects expressions outright with a line/column error. Use static string attributes if you need parameterised components.

What components are allowed?

Callout, Note, Warning, CodeBlock, Tabs, Steps, Image. Anything else renders as a labeled fallback block instead of being silently dropped — useful when porting MDX from another tool.

Can I import other components?

No. ESM imports are blocked at parse so the converter has zero ability to load arbitrary user code. Adding a component to the allowlist is a code change, not config.

How is the Image component safer than markdown ![]()?

Both flow through the same SSRF guard: scheme allowlist, DNS-resolution block on private/loopback/link-local IPs, redirect rejection, 5s timeout, 5 MB size cap. The MDX <Image> just exposes that guard explicitly.

Will Tabs interactivity work in the PDF?

No — PDF and DOCX have no tab UI. Each tab is rendered as a section heading followed by the tab's body, in order. HTML keeps the same linear layout for consistency.

More converters

Migrating off DoczJS? Read our DoczJS migration guide →