LAB_MENU
Playground Pipeline Typography Features Install GitHub
V0.3.0 Alive on Crates.io

The
Monster
Markdown
Engine.

Stitched together from a clean-room parser, LaTeX-grade typesetting, and a hand-rolled PDF writer — one auditable Rust core with zero dependencies that renders Markdown to beautiful self-contained HTML and compact tagged PDF. Natively, and in this very page via WASM. Byte-for-byte identical.

fmd_render_stream
Live Session

          
Core Crates
0deps
Engine Dependencies
0
the core is 100% our Rust
Native ↔ WASM Parity
100%
byte-identical HTML + PDF, gated in CI
CommonMark Ratchet
379
conformance floor that can only rise
WASM Payload
1.5MB gz
fonts, highlighter & PDF writer included
SPECIMEN_001 · LIVE EXPERIMENT

The Operating Theater.

Type Markdown on the left. The actual engine — compiled to WebAssembly, running in a worker in your browser — renders it on the right. Flip the switch to typeset the same document as a PDF. No server. No mock. The monster itself.

fmd_playground
REANIMATING…
Sample
source.md 0 B
self_contained.html RENDERED_IN_BROWSER
Diagnostics
⚡ Serverless sharing — the document is the link

Share compresses your Markdown with deflate, base64url-encodes it, and packs it into the # fragment of the URL — like franken-markdown.com/#view=max&zdoc=…. Nothing is uploaded, stored, or logged: URL fragments are never even sent to the server, and this site has no backend anyway. Whoever opens your link gets the exact document, decompressed and re-typeset locally by the same wasm engine. Documents up to roughly 30 KB of URL travel well in every modern browser.

Deep links

The playground itself is linkable. Fragment parameters compose:

  • /#view=max — open the playground maximized, full page
  • /#fmt=pdf — start on the PDF pane
  • /#zdoc=… — deflated + base64url document payload
  • /#doc=… — plain base64url payload (no compression)
SUBSYSTEM_MAP

One AST. Every Organ.

Parse once; render everywhere. HTML, PDF, and WASM read the same tree and the same typed theme, so the surfaces can never drift apart. Click a stage to dissect it.

markdown file · stdin · string clean-room parser byte-level scanner document AST one parse, many bodies theme model colors · spacing · page HTML emitter self-contained page layout + PDF writer Knuth–Plass · tagged WASM ABI this page, right now

VITAL_ORGANS

Built Different.

Every organ in the render path — parser, highlighter, font reader, line breaker, compressor, PDF writer — was grown in this lab, for this exact workflow.

One AST, Two Bodies

HTML and PDF render from the same parse and the same typed theme. Colors, spacing, code styling, and document rhythm stay coherent across surfaces — structurally, not by convention.

Zero-Dependency Core

No comrak, no syntect, no PDF crates, no regex engine. The engine compiles with zero third-party crates (clap exists only for the CLI), enforced by a CI policy gate. Tiny audit surface, fast builds.

Deterministic Bytes

Fixed input + fixed options = identical output bytes, across runs and operating systems. SOURCE_DATE_EPOCH pins PDF dates; CI diffs repeated renders byte-for-byte. Perfect for reproducible builds and caching.

LaTeX-Grade Typography

Knuth–Plass optimal paragraph breaking, Liang hyphenation, real font metrics, GPOS kerning, GSUB ligatures, and measured-column tables. PDF output that reads like it was typeset, because it was.

Clean-Room Highlighter

Rust, Python, JS/TS, JSON, shell, PowerShell, Go, C/C++, TOML, YAML, SQL, HTML/SVG, CSS, Markdown, and Mermaid — one hand-written highlighting model shared by HTML and PDF. Diagram-shaped ASCII keeps its geometry.

Agent-First CLI

The first command an agent guesses works: fmd README.md. Stdout is data, stderr is diagnostics, exit codes are stable, and capabilities --json, doctor --json, and robot-docs expose the whole contract.

TYPE_LAB

Typeset Like TeX.

Word processors break lines greedily: fill until full, wrap, repeat — and one bad line poisons the paragraph. FrankenMarkdown's PDF path uses the Knuth–Plass total-fit algorithm: it considers every possible set of breakpoints and picks the one that minimizes ugliness across the whole paragraph. This demo runs both algorithms live. Drag the measure and watch the line tinting: the hotter a line, the more its spaces were stretched or squeezed.

Line width 492px measure
Greedy (first-fit) — what most tools do
Knuth–Plass (total-fit) — what fmd does
comfortable spacing stretched abused — hover any line for its adjustment ratio and badness. Same font, same words, same widths; only the breakpoints differ.
FONT_SURGERY

Only the Glyphs You Use.

Both output bodies embed real fonts — but never whole ones. The clean-room TrueType reader walks cmap, glyf and loca, keeps exactly the outlines your document touches, and rebuilds a valid font. That's how a fully typeset PDF of the project README — embedded fonts, kerning, ligatures and all — lands around 58 KB.

Type below and watch the subset grow glyph by glyph. Deterministic ordering means the same document always produces the same font bytes.

Glyph inventory (printable ASCII) 0 / 94 kept
full face on disk269 KB
embedded subset
AUDIT_SURFACE

No Organ Donors.

Assemble a Markdown→HTML+PDF pipeline the usual way and you inherit a dependency forest — parser, regex engine, syntax themes, font stack, PDF library, image codecs. Every crate is code you now ship, audit, and trust. The monster grows its own organs.

The usual stack 36+ crates

comrak + syntect + a PDF crate, resolved transitively. Each node: someone else's unsafe review queue.

franken_markdown 0 crates
franken_ markdown clap CLI only, never in core/wasm parser · highlighter · fonts · layout · SVG · DEFLATE · PDF — all in-tree

One codebase. cargo tree proof gated in CI; unsafe forbidden at the crate level.

Approach FrankenMarkdown Headless Chrome Pandoc + LaTeX comrak + syntect + PDF crate
Install weight one small binary / 1.5 MB wasm a whole browser Haskell + TeX distribution large crate forest
PDF typography Knuth–Plass, kerning, ligatures, tagged browser print pipeline excellent (TeX) whatever the crate does
Deterministic bytes yes, CI-enforced no with effort rarely
Runs in the browser yes — this page it is the browser no partially
Third-party code in the render path zero crates millions of lines very large dozens of crates

Honest tradeoff: a browser out-renders arbitrary CSS and Pandoc converts more formats. fmd trades breadth for focus, determinism, and a surface you can actually audit.

REANIMATION_PROTOCOL

Get Stitched In.

cargo (released CLI)
$ cargo install franken_markdown
one-liner (checksum-verified binaries)
$ curl -fsSL https://raw.githubusercontent.com/Dicklesworthstone/franken_markdown/main/install.sh | bash
first commands
$ fmd README.md --out README.html          # self-contained HTML
$ fmd README.md --to pdf --out README.pdf   # compact tagged PDF
$ fmd README.md --to both --out README.html # one parse, both bodies
$ fmd capabilities --json                   # the machine-readable contract
npm (browser / bundler package)
$ npm install @franken-suite/franken-markdown   # or: bun add @franken-suite/franken-markdown
browser (the API powering this page)
import { createRenderer } from "@franken-suite/franken-markdown";

const fmd  = await createRenderer();
const html = await fmd.renderHtml("# Hello", { font: "sans" });
const pdf  = await fmd.renderPdf("# Report", { metadataEpochSeconds: 1700000000 });
LAB_NOTES · Honest scar tissue
  • CommonMark coverage is partial and measured: 379/652 examples (64.1% of in-scope; raw-HTML passthrough is an intentional non-goal) — a CI-ratcheted floor.
  • The npm package @franken-suite/franken-markdown ships the exact parity-gated build this page runs; browser visual/golden fixtures are still early.
  • PDF pagination is still maturing: keep-with-next and repeatable table headers work; full widow/orphan control is roadmap.
  • SVG support is practical, not browser-complete — unsupported constructs surface as structured render warnings, never silent lies.