Last month I shipped MD2PDF Online β a free tool that converts Markdown to PDF, Word, HTML and Mind Map, with zero server-side processing. Everything runs client-side.
Here's what I learned building it and why the approach matters.
The Problem
Most online converters upload your file to a server, process it, then send back the result. This works, but:
- Your document content leaves your device
- There are file size limits
- Server costs scale with usage
- Privacy concerns for sensitive documents
I wanted a converter where the browser does all the work. Your Markdown never leaves your computer.
The Architecture
ββββββββββββββββββββββββββββββββββββββββββββββββ
β Browser β
β β
β βββββββββββ ββββββββββββ βββββββββββ β
β β Code βββββΆβ Parser βββββΆβ Export β β
β β Mirror β β (remark)β β (html2pdf)β β
β βββββββββββ ββββββββββββ βββββββββββ β
β β
β No server calls. No file uploads. β
ββββββββββββββββββββββββββββββββββββββββββββββββ
1. Markdown Parsing
I used the unified ecosystem with remark-parse, remark-gfm, and rehype-stringify. This gives me GitHub-Flavored Markdown support including tables, task lists, and strikethrough.
import { unified } from "unified";
import remarkParse from "remark-parse";
import remarkGfm from "remark-gfm";
import remarkRehype from "remark-rehype";
import rehypeStringify from "rehype-stringify";
async function markdownToHtml(md: string) {
return String(
await unified()
.use(remarkParse)
.use(remarkGfm)
.use(remarkRehype)
.use(rehypeStringify)
.process(md)
);
}
The parser runs synchronously in the browser. No API calls.
2. PDF Generation
Instead of sending the HTML to a server and waiting for a PDF back, I use html2pdf.js β a client-side wrapper around html2canvas and jsPDF:
import html2pdf from "html2pdf.js";
function exportToPdf(htmlContent: string) {
const element = document.createElement("div");
element.innerHTML = htmlContent;
document.body.appendChild(element);
html2pdf().from(element).save();
}
This renders the HTML as a canvas, then converts it to a PDF. The trade-off is that it's a rasterized PDF (not vector), but for most use cases it's perfectly fine and the zero-server approach is worth it.
3. Word Export
For DOCX, I used the docx library:
import { Document, Packer, Paragraph, TextRun } from "docx";
const doc = new Document({
sections: [{ children: paragraphs }],
});
const blob = await Packer.toBlob(doc);
saveAs(blob, "document.docx");
4. Mind Map Generation
This was the most interesting part. I used markmap-lib to parse Markdown headings and lists into a hierarchical data structure, then rendered it with markmap-view as an interactive SVG mind map:
import { Transformer } from "markmap-lib";
const transformer = new Transformer();
const { root, features } = transformer.transform(markdown);
Key Challenges
Client-Side Performance
Running everything in the browser means the main thread can get busy. I solved this by:
- Lazy loading heavy libraries (html2pdf, docx, markmap) only when the user clicks export
- Using useMemo and React.lazy in Next.js to avoid re-parsing
- Debouncing the editor input at 100ms
Internationalization
The tool supports 6 languages (English, Chinese, Japanese, French, German, Spanish). I used next-intl with the new App Router. Each language gets its own URL (/en, /zh, /ja etc.) with proper hreflang tags for SEO.
The PDF-to-Markdown Pipeline
Converting PDF back to Markdown is harder because the browser can't run OCR. I used @opendocsg/pdf2md which works well for PDFs with selectable text. For scanned PDFs, I recommend local tools like Tesseract.
Why This Matters
The "process everything in the browser" approach has real benefits:
| Server-side | Client-side |
|---|---|
| File uploads to remote servers | File stays on your device |
| Server costs scale with traffic | Free to run (static hosting) |
| Privacy concerns | Zero data collection |
| Rate limits needed | No limits |
For a simple converter, there's no reason to send files to a server. Modern browsers are powerful enough to handle the entire pipeline locally.
Want to Try It?
You can use it for free at https://md2dfonline.com. No signup, no tracking, no file uploads. The code is a standard Next.js app β I'm happy to answer any questions about the architecture or tradeoffs in the comments.
What's your favorite browser-based productivity tool?
United States
NORTH AMERICA
Related News
UCP Variant Data: The #1 Reason Agent Checkouts Fail
7h ago
Amazon Employees Are 'Tokenmaxxing' Due To Pressure To Use AI Tools
21h ago
How Brazeβs CTO is rethinking engineering for the agentic area
10h ago

DΓ©cryptage technique : Comment builder un tΓ©lΓ©chargeur de vidΓ©os Reddit performant (DASH, HLS & WebAssembly)
17h ago
How AI Reduced Manual Driver Verification by 75% β Operations Case Study. Part 2
4h ago