DEV Community

jom hou
jom hou

Posted on

How I built a Markdown-to-PDF export tool with Next.js (and what I learned)

How I built a Markdown-to-PDF export tool with Next.js (and what I learned)

I've been building side projects for a while, but Markdownary is the first one I actually shipped and put in front of real users.

The core feature sounds simple: write Markdown, export to PDF. But getting it to work well turned out to be surprisingly tricky.

The problem with browser-based PDF export

Most Markdown-to-PDF tools use one of two approaches:

  1. window.print() — quick and dirty, but the output looks like a printed webpage
  2. Puppeteer/headless Chrome — accurate, but heavy, slow to cold-start, and expensive to host

I wanted something that produced clean, typographically correct PDFs without spinning up a full browser instance on every request.

The solution: server-side rendering with a Skia-based engine

I ended up using a server-side Markdown rendering engine built on Skia Canvas — the same graphics library that powers Chrome's rendering. It processes Markdown on the server and produces vector-quality output without needing a headless browser.

The result: PDFs that look like they were designed, not printed.

Tech stack

  • Next.js 15 (App Router) — API routes handle all export logic server-side
  • TypeScript throughout
  • Tailwind CSS 4 for the editor UI
  • react-markdown + remark-gfm for live preview
  • PM2 cluster mode for production deployment

What the app does

Markdownary is a clean, distraction-free Markdown editor with:

  • Export to PDF, Word (.docx), PNG, and HTML
  • 6 themes with live preview (light, dark, warm, bamboo, ocean, rose)
  • No login required — open and start writing
  • Import .md, .docx, .txt files
  • Synchronized scroll between editor and preview
  • Mobile-friendly toolbar

Lessons learned

1. PDF quality is a UX differentiator

Users notice immediately when PDF output looks bad. Investing in a proper rendering engine made the biggest difference in early feedback.

2. "No login" is a feature

Removing the signup wall increased the conversion from "landing page visitor" to "actual user" dramatically. People just want to try it.

3. Character limits matter

Without a content size limit on the export API, a single large document can spike memory usage and affect all users. I added a 300k character cap with a clear error message.

4. Mobile is non-negotiable

Even for a "desktop" tool like a Markdown editor, ~30% of initial visits came from mobile. A collapsed toolbar with the most-used actions (bold, italic, heading, list) surfaced made a huge difference.

What's next

  • Google AdSense integration (currently in review)
  • More export themes
  • Collaborative editing (maybe)

If you're into Markdown, writing tools, or just want to try it out:

👉 https://markdownary.com

Would love feedback — especially on the PDF output quality and anything that feels broken on mobile.

Top comments (0)